oh-my-oop 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/MCP_STRUCTURE.md +301 -0
- package/README.md +167 -0
- package/SCOPE.md +27 -0
- package/dist/application/discovery.d.ts +133 -0
- package/dist/application/discovery.js +62 -0
- package/dist/application/discovery.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +80 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +16 -0
- package/dist/config.js +32 -0
- package/dist/config.js.map +1 -0
- package/dist/domain/collaborators.d.ts +2 -0
- package/dist/domain/collaborators.js +26 -0
- package/dist/domain/collaborators.js.map +1 -0
- package/dist/domain/ids.d.ts +4 -0
- package/dist/domain/ids.js +23 -0
- package/dist/domain/ids.js.map +1 -0
- package/dist/domain/model.d.ts +71 -0
- package/dist/domain/model.js +2 -0
- package/dist/domain/model.js.map +1 -0
- package/dist/domain/schemas.d.ts +213 -0
- package/dist/domain/schemas.js +79 -0
- package/dist/domain/schemas.js.map +1 -0
- package/dist/domain/stereotypes.d.ts +7 -0
- package/dist/domain/stereotypes.js +65 -0
- package/dist/domain/stereotypes.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +21 -0
- package/dist/index.js.map +1 -0
- package/dist/io/classStore.d.ts +9 -0
- package/dist/io/classStore.js +39 -0
- package/dist/io/classStore.js.map +1 -0
- package/dist/io/collaborationStore.d.ts +7 -0
- package/dist/io/collaborationStore.js +32 -0
- package/dist/io/collaborationStore.js.map +1 -0
- package/dist/io/design.d.ts +3 -0
- package/dist/io/design.js +22 -0
- package/dist/io/design.js.map +1 -0
- package/dist/io/designIndex.d.ts +6 -0
- package/dist/io/designIndex.js +49 -0
- package/dist/io/designIndex.js.map +1 -0
- package/dist/io/frontmatter.d.ts +8 -0
- package/dist/io/frontmatter.js +31 -0
- package/dist/io/frontmatter.js.map +1 -0
- package/dist/io/history.d.ts +10 -0
- package/dist/io/history.js +38 -0
- package/dist/io/history.js.map +1 -0
- package/dist/io/useCaseStore.d.ts +8 -0
- package/dist/io/useCaseStore.js +36 -0
- package/dist/io/useCaseStore.js.map +1 -0
- package/dist/io/workspace.d.ts +14 -0
- package/dist/io/workspace.js +82 -0
- package/dist/io/workspace.js.map +1 -0
- package/dist/oop/commands.d.ts +446 -0
- package/dist/oop/commands.js +319 -0
- package/dist/oop/commands.js.map +1 -0
- package/dist/oop/conformance.d.ts +16 -0
- package/dist/oop/conformance.js +30 -0
- package/dist/oop/conformance.js.map +1 -0
- package/dist/prompts/discovery.d.ts +2 -0
- package/dist/prompts/discovery.js +41 -0
- package/dist/prompts/discovery.js.map +1 -0
- package/dist/prompts/imagineWithoutController.d.ts +2 -0
- package/dist/prompts/imagineWithoutController.js +75 -0
- package/dist/prompts/imagineWithoutController.js.map +1 -0
- package/dist/prompts/index.d.ts +2 -0
- package/dist/prompts/index.js +17 -0
- package/dist/prompts/index.js.map +1 -0
- package/dist/prompts/phasePressureTest.d.ts +2 -0
- package/dist/prompts/phasePressureTest.js +69 -0
- package/dist/prompts/phasePressureTest.js.map +1 -0
- package/dist/prompts/rddIntro.d.ts +2 -0
- package/dist/prompts/rddIntro.js +53 -0
- package/dist/prompts/rddIntro.js.map +1 -0
- package/dist/prompts/review.d.ts +2 -0
- package/dist/prompts/review.js +45 -0
- package/dist/prompts/review.js.map +1 -0
- package/dist/prompts/stateMachineIntrospect.d.ts +2 -0
- package/dist/prompts/stateMachineIntrospect.js +80 -0
- package/dist/prompts/stateMachineIntrospect.js.map +1 -0
- package/dist/prompts/tellDontAskRephrase.d.ts +2 -0
- package/dist/prompts/tellDontAskRephrase.js +66 -0
- package/dist/prompts/tellDontAskRephrase.js.map +1 -0
- package/dist/render/diff.d.ts +21 -0
- package/dist/render/diff.js +84 -0
- package/dist/render/diff.js.map +1 -0
- package/dist/render/mermaid.d.ts +24 -0
- package/dist/render/mermaid.js +53 -0
- package/dist/render/mermaid.js.map +1 -0
- package/dist/render/sideBySide.d.ts +14 -0
- package/dist/render/sideBySide.js +91 -0
- package/dist/render/sideBySide.js.map +1 -0
- package/dist/resources/index.d.ts +2 -0
- package/dist/resources/index.js +349 -0
- package/dist/resources/index.js.map +1 -0
- package/dist/server.d.ts +2 -0
- package/dist/server.js +22 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/alternatives.d.ts +2 -0
- package/dist/tools/alternatives.js +9 -0
- package/dist/tools/alternatives.js.map +1 -0
- package/dist/tools/classes.d.ts +2 -0
- package/dist/tools/classes.js +13 -0
- package/dist/tools/classes.js.map +1 -0
- package/dist/tools/collaborations.d.ts +2 -0
- package/dist/tools/collaborations.js +8 -0
- package/dist/tools/collaborations.js.map +1 -0
- package/dist/tools/compare.d.ts +2 -0
- package/dist/tools/compare.js +9 -0
- package/dist/tools/compare.js.map +1 -0
- package/dist/tools/conformance.d.ts +3 -0
- package/dist/tools/conformance.js +11 -0
- package/dist/tools/conformance.js.map +1 -0
- package/dist/tools/diagram.d.ts +2 -0
- package/dist/tools/diagram.js +9 -0
- package/dist/tools/diagram.js.map +1 -0
- package/dist/tools/discovery.d.ts +2 -0
- package/dist/tools/discovery.js +23 -0
- package/dist/tools/discovery.js.map +1 -0
- package/dist/tools/index.d.ts +2 -0
- package/dist/tools/index.js +27 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/init.d.ts +2 -0
- package/dist/tools/init.js +9 -0
- package/dist/tools/init.js.map +1 -0
- package/dist/tools/oop.d.ts +9 -0
- package/dist/tools/oop.js +26 -0
- package/dist/tools/oop.js.map +1 -0
- package/dist/tools/responsibilities.d.ts +2 -0
- package/dist/tools/responsibilities.js +13 -0
- package/dist/tools/responsibilities.js.map +1 -0
- package/dist/tools/state.d.ts +2 -0
- package/dist/tools/state.js +8 -0
- package/dist/tools/state.js.map +1 -0
- package/dist/tools/useCases.d.ts +2 -0
- package/dist/tools/useCases.js +18 -0
- package/dist/tools/useCases.js.map +1 -0
- package/dist/tools/validate.d.ts +2 -0
- package/dist/tools/validate.js +9 -0
- package/dist/tools/validate.js.map +1 -0
- package/dist/tradeoff/engine.d.ts +61 -0
- package/dist/tradeoff/engine.js +171 -0
- package/dist/tradeoff/engine.js.map +1 -0
- package/dist/tradeoff/heuristics/classSplit.d.ts +3 -0
- package/dist/tradeoff/heuristics/classSplit.js +94 -0
- package/dist/tradeoff/heuristics/classSplit.js.map +1 -0
- package/dist/tradeoff/heuristics/collaborationShape.d.ts +2 -0
- package/dist/tradeoff/heuristics/collaborationShape.js +82 -0
- package/dist/tradeoff/heuristics/collaborationShape.js.map +1 -0
- package/dist/tradeoff/heuristics/collectionShape.d.ts +2 -0
- package/dist/tradeoff/heuristics/collectionShape.js +113 -0
- package/dist/tradeoff/heuristics/collectionShape.js.map +1 -0
- package/dist/tradeoff/heuristics/dualSubjectComparison.d.ts +2 -0
- package/dist/tradeoff/heuristics/dualSubjectComparison.js +114 -0
- package/dist/tradeoff/heuristics/dualSubjectComparison.js.map +1 -0
- package/dist/tradeoff/heuristics/errorHandling.d.ts +2 -0
- package/dist/tradeoff/heuristics/errorHandling.js +110 -0
- package/dist/tradeoff/heuristics/errorHandling.js.map +1 -0
- package/dist/tradeoff/heuristics/responsibilitySplit.d.ts +23 -0
- package/dist/tradeoff/heuristics/responsibilitySplit.js +183 -0
- package/dist/tradeoff/heuristics/responsibilitySplit.js.map +1 -0
- package/dist/tradeoff/heuristics/stereotypeChoice.d.ts +2 -0
- package/dist/tradeoff/heuristics/stereotypeChoice.js +23 -0
- package/dist/tradeoff/heuristics/stereotypeChoice.js.map +1 -0
- package/dist/tradeoff/heuristics/strategyOrPolicy.d.ts +2 -0
- package/dist/tradeoff/heuristics/strategyOrPolicy.js +110 -0
- package/dist/tradeoff/heuristics/strategyOrPolicy.js.map +1 -0
- package/dist/tradeoff/heuristics/valueObjectShape.d.ts +2 -0
- package/dist/tradeoff/heuristics/valueObjectShape.js +111 -0
- package/dist/tradeoff/heuristics/valueObjectShape.js.map +1 -0
- package/dist/tradeoff/templates.d.ts +2 -0
- package/dist/tradeoff/templates.js +33 -0
- package/dist/tradeoff/templates.js.map +1 -0
- package/dist/util/log.d.ts +1 -0
- package/dist/util/log.js +7 -0
- package/dist/util/log.js.map +1 -0
- package/dist/util/mcp.d.ts +4 -0
- package/dist/util/mcp.js +18 -0
- package/dist/util/mcp.js.map +1 -0
- package/dist/validate/cohesion.d.ts +3 -0
- package/dist/validate/cohesion.js +88 -0
- package/dist/validate/cohesion.js.map +1 -0
- package/dist/validate/collectionWrapper.d.ts +3 -0
- package/dist/validate/collectionWrapper.js +131 -0
- package/dist/validate/collectionWrapper.js.map +1 -0
- package/dist/validate/coupling.d.ts +3 -0
- package/dist/validate/coupling.js +47 -0
- package/dist/validate/coupling.js.map +1 -0
- package/dist/validate/cycle.d.ts +3 -0
- package/dist/validate/cycle.js +101 -0
- package/dist/validate/cycle.js.map +1 -0
- package/dist/validate/dataDuplication.d.ts +3 -0
- package/dist/validate/dataDuplication.js +150 -0
- package/dist/validate/dataDuplication.js.map +1 -0
- package/dist/validate/dependencyDirection.d.ts +3 -0
- package/dist/validate/dependencyDirection.js +106 -0
- package/dist/validate/dependencyDirection.js.map +1 -0
- package/dist/validate/dualUseKnowing.d.ts +3 -0
- package/dist/validate/dualUseKnowing.js +137 -0
- package/dist/validate/dualUseKnowing.js.map +1 -0
- package/dist/validate/emptyObjectFill.d.ts +3 -0
- package/dist/validate/emptyObjectFill.js +119 -0
- package/dist/validate/emptyObjectFill.js.map +1 -0
- package/dist/validate/findings.d.ts +22 -0
- package/dist/validate/findings.js +12 -0
- package/dist/validate/findings.js.map +1 -0
- package/dist/validate/functionDecompositionExcess.d.ts +3 -0
- package/dist/validate/functionDecompositionExcess.js +120 -0
- package/dist/validate/functionDecompositionExcess.js.map +1 -0
- package/dist/validate/functionNotObject.d.ts +3 -0
- package/dist/validate/functionNotObject.js +80 -0
- package/dist/validate/functionNotObject.js.map +1 -0
- package/dist/validate/godObject.d.ts +6 -0
- package/dist/validate/godObject.js +76 -0
- package/dist/validate/godObject.js.map +1 -0
- package/dist/validate/presentationInDomain.d.ts +3 -0
- package/dist/validate/presentationInDomain.js +57 -0
- package/dist/validate/presentationInDomain.js.map +1 -0
- package/dist/validate/primitiveWrapper.d.ts +3 -0
- package/dist/validate/primitiveWrapper.js +106 -0
- package/dist/validate/primitiveWrapper.js.map +1 -0
- package/dist/validate/rules.d.ts +24 -0
- package/dist/validate/rules.js +269 -0
- package/dist/validate/rules.js.map +1 -0
- package/dist/validate/singletonStatefulHolder.d.ts +3 -0
- package/dist/validate/singletonStatefulHolder.js +128 -0
- package/dist/validate/singletonStatefulHolder.js.map +1 -0
- package/dist/validate/strategyAsymmetry.d.ts +3 -0
- package/dist/validate/strategyAsymmetry.js +131 -0
- package/dist/validate/strategyAsymmetry.js.map +1 -0
- package/dist/validate/testability.d.ts +5 -0
- package/dist/validate/testability.js +157 -0
- package/dist/validate/testability.js.map +1 -0
- package/dist/validate/vagueName.d.ts +3 -0
- package/dist/validate/vagueName.js +136 -0
- package/dist/validate/vagueName.js.map +1 -0
- package/dist/validate/validationLocation.d.ts +3 -0
- package/dist/validate/validationLocation.js +120 -0
- package/dist/validate/validationLocation.js.map +1 -0
- package/lessons/STYLE_GUIDE.md +304 -0
- package/lessons/woowacourse-kotlin-blackjack/2chang5/33-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +293 -0
- package/lessons/woowacourse-kotlin-blackjack/Choisehyeon/52-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +106 -0
- package/lessons/woowacourse-kotlin-blackjack/Choisehyeon/9-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +282 -0
- package/lessons/woowacourse-kotlin-blackjack/DYGames/14-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +182 -0
- package/lessons/woowacourse-kotlin-blackjack/DYGames/37-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +122 -0
- package/lessons/woowacourse-kotlin-blackjack/EmilyCh0/12-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +117 -0
- package/lessons/woowacourse-kotlin-blackjack/EmilyCh0/38-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +291 -0
- package/lessons/woowacourse-kotlin-blackjack/HANDOVER.md +1475 -0
- package/lessons/woowacourse-kotlin-blackjack/HamBeomJoon/119-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +251 -0
- package/lessons/woowacourse-kotlin-blackjack/HamBeomJoon/137-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +459 -0
- package/lessons/woowacourse-kotlin-blackjack/Hevton/100-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +282 -0
- package/lessons/woowacourse-kotlin-blackjack/Hevton/82-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +303 -0
- package/lessons/woowacourse-kotlin-blackjack/Hogu59/71-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +134 -0
- package/lessons/woowacourse-kotlin-blackjack/Hogu59/96-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +323 -0
- package/lessons/woowacourse-kotlin-blackjack/JoYehyun99/66-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +210 -0
- package/lessons/woowacourse-kotlin-blackjack/Junyoung-WON/101-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +191 -0
- package/lessons/woowacourse-kotlin-blackjack/Junyoung-WON/80-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +253 -0
- package/lessons/woowacourse-kotlin-blackjack/Leeyerin0210/108-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +516 -0
- package/lessons/woowacourse-kotlin-blackjack/Leeyerin0210/133-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +541 -0
- package/lessons/woowacourse-kotlin-blackjack/RightHennessy/22-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +278 -0
- package/lessons/woowacourse-kotlin-blackjack/RightHennessy/48-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +188 -0
- package/lessons/woowacourse-kotlin-blackjack/SeongHoonC/16-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +228 -0
- package/lessons/woowacourse-kotlin-blackjack/SeongHoonC/54-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +227 -0
- package/lessons/woowacourse-kotlin-blackjack/Yunseok-Nam/76-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +279 -0
- package/lessons/woowacourse-kotlin-blackjack/Yunseok-Nam/86-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +203 -0
- package/lessons/woowacourse-kotlin-blackjack/aprilgom/105-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +162 -0
- package/lessons/woowacourse-kotlin-blackjack/aprilgom/64-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +279 -0
- package/lessons/woowacourse-kotlin-blackjack/boogi-woogi/18-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +188 -0
- package/lessons/woowacourse-kotlin-blackjack/boogi-woogi/36-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +769 -0
- package/lessons/woowacourse-kotlin-blackjack/briandr97/19-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +226 -0
- package/lessons/woowacourse-kotlin-blackjack/briandr97/59-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +193 -0
- package/lessons/woowacourse-kotlin-blackjack/chaehyuns/70-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +175 -0
- package/lessons/woowacourse-kotlin-blackjack/chaehyuns/98-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +206 -0
- package/lessons/woowacourse-kotlin-blackjack/chanho0908/123-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +277 -0
- package/lessons/woowacourse-kotlin-blackjack/chanho0908/150-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +219 -0
- package/lessons/woowacourse-kotlin-blackjack/chws0508/26-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +259 -0
- package/lessons/woowacourse-kotlin-blackjack/chws0508/43-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +189 -0
- package/lessons/woowacourse-kotlin-blackjack/cucumber99/109-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +351 -0
- package/lessons/woowacourse-kotlin-blackjack/cucumber99/149-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +147 -0
- package/lessons/woowacourse-kotlin-blackjack/devfeijoa/121-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +168 -0
- package/lessons/woowacourse-kotlin-blackjack/devfeijoa/153-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +116 -0
- package/lessons/woowacourse-kotlin-blackjack/doabletuple/126-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +680 -0
- package/lessons/woowacourse-kotlin-blackjack/doabletuple/142-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +739 -0
- package/lessons/woowacourse-kotlin-blackjack/donghyun81/116-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +297 -0
- package/lessons/woowacourse-kotlin-blackjack/donghyun81/147-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +244 -0
- package/lessons/woowacourse-kotlin-blackjack/dpcks0509/78-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +232 -0
- package/lessons/woowacourse-kotlin-blackjack/dpcks0509/88-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +137 -0
- package/lessons/woowacourse-kotlin-blackjack/etama123/112-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +269 -0
- package/lessons/woowacourse-kotlin-blackjack/etama123/148-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +240 -0
- package/lessons/woowacourse-kotlin-blackjack/gaeun5744/102-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +146 -0
- package/lessons/woowacourse-kotlin-blackjack/gaeun5744/69-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +224 -0
- package/lessons/woowacourse-kotlin-blackjack/gahyunkim/118-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +397 -0
- package/lessons/woowacourse-kotlin-blackjack/gahyunkim/141-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +215 -0
- package/lessons/woowacourse-kotlin-blackjack/giovannijunseokim/106-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +395 -0
- package/lessons/woowacourse-kotlin-blackjack/giovannijunseokim/134-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +219 -0
- package/lessons/woowacourse-kotlin-blackjack/haeum808/62-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +230 -0
- package/lessons/woowacourse-kotlin-blackjack/haeum808/89-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +169 -0
- package/lessons/woowacourse-kotlin-blackjack/hwannow/110-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +221 -0
- package/lessons/woowacourse-kotlin-blackjack/hwannow/132-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +573 -0
- package/lessons/woowacourse-kotlin-blackjack/hxeyexn/103-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +188 -0
- package/lessons/woowacourse-kotlin-blackjack/hxeyexn/81-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +301 -0
- package/lessons/woowacourse-kotlin-blackjack/hyemdooly/21-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +613 -0
- package/lessons/woowacourse-kotlin-blackjack/hyemdooly/35-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +691 -0
- package/lessons/woowacourse-kotlin-blackjack/hyunji1203/13-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +206 -0
- package/lessons/woowacourse-kotlin-blackjack/ii2001/79-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +153 -0
- package/lessons/woowacourse-kotlin-blackjack/ii2001/85-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +318 -0
- package/lessons/woowacourse-kotlin-blackjack/ijh1298/128-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +250 -0
- package/lessons/woowacourse-kotlin-blackjack/ijh1298/135-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +269 -0
- package/lessons/woowacourse-kotlin-blackjack/inseonyun/28-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +346 -0
- package/lessons/woowacourse-kotlin-blackjack/inseonyun/49-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +360 -0
- package/lessons/woowacourse-kotlin-blackjack/ippnsj/30-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +152 -0
- package/lessons/woowacourse-kotlin-blackjack/ippnsj/42-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +213 -0
- package/lessons/woowacourse-kotlin-blackjack/jaeyeongjo/73-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +247 -0
- package/lessons/woowacourse-kotlin-blackjack/jaeyeongjo/87-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +900 -0
- package/lessons/woowacourse-kotlin-blackjack/jerry8282/125-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +248 -0
- package/lessons/woowacourse-kotlin-blackjack/jerry8282/151-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +243 -0
- package/lessons/woowacourse-kotlin-blackjack/jinuemong/63-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +281 -0
- package/lessons/woowacourse-kotlin-blackjack/jinuemong/92-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +283 -0
- package/lessons/woowacourse-kotlin-blackjack/jiyuneel/113-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +348 -0
- package/lessons/woowacourse-kotlin-blackjack/jiyuneel/140-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +265 -0
- package/lessons/woowacourse-kotlin-blackjack/junjange/61-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +270 -0
- package/lessons/woowacourse-kotlin-blackjack/junjange/93-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +465 -0
- package/lessons/woowacourse-kotlin-blackjack/junseo511/107-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +296 -0
- package/lessons/woowacourse-kotlin-blackjack/junseo511/145-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +316 -0
- package/lessons/woowacourse-kotlin-blackjack/ki960213/11-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +175 -0
- package/lessons/woowacourse-kotlin-blackjack/kimhm0728/72-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +458 -0
- package/lessons/woowacourse-kotlin-blackjack/kimhm0728/97-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +225 -0
- package/lessons/woowacourse-kotlin-blackjack/kkosang/68-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +221 -0
- package/lessons/woowacourse-kotlin-blackjack/kkosang/94-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +158 -0
- package/lessons/woowacourse-kotlin-blackjack/kmkim2689/65-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +252 -0
- package/lessons/woowacourse-kotlin-blackjack/kmkim2689/90-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +460 -0
- package/lessons/woowacourse-kotlin-blackjack/krrong/32-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +216 -0
- package/lessons/woowacourse-kotlin-blackjack/krrong/46-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +285 -0
- package/lessons/woowacourse-kotlin-blackjack/m6z1/122-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +177 -0
- package/lessons/woowacourse-kotlin-blackjack/m6z1/144-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +155 -0
- package/lessons/woowacourse-kotlin-blackjack/medAndro/130-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +683 -0
- package/lessons/woowacourse-kotlin-blackjack/medAndro/143-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +678 -0
- package/lessons/woowacourse-kotlin-blackjack/moondev03/114-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +262 -0
- package/lessons/woowacourse-kotlin-blackjack/moondev03/131-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +498 -0
- package/lessons/woowacourse-kotlin-blackjack/murjune/77-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +287 -0
- package/lessons/woowacourse-kotlin-blackjack/murjune/91-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +280 -0
- package/lessons/woowacourse-kotlin-blackjack/no1msh/31-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +250 -0
- package/lessons/woowacourse-kotlin-blackjack/otter66/24-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +302 -0
- package/lessons/woowacourse-kotlin-blackjack/otter66/58-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +391 -0
- package/lessons/woowacourse-kotlin-blackjack/oungsi2000/111-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +253 -0
- package/lessons/woowacourse-kotlin-blackjack/oungsi2000/136-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +540 -0
- package/lessons/woowacourse-kotlin-blackjack/parkjiminnnn/117-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +819 -0
- package/lessons/woowacourse-kotlin-blackjack/parkjiminnnn/139-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +683 -0
- package/lessons/woowacourse-kotlin-blackjack/pingu244/20-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +258 -0
- package/lessons/woowacourse-kotlin-blackjack/pingu244/41-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +171 -0
- package/lessons/woowacourse-kotlin-blackjack/re4rk/34-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +289 -0
- package/lessons/woowacourse-kotlin-blackjack/re4rk/8-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +297 -0
- package/lessons/woowacourse-kotlin-blackjack/rhkrwngud445/17-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +279 -0
- package/lessons/woowacourse-kotlin-blackjack/rhkrwngud445/50-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +145 -0
- package/lessons/woowacourse-kotlin-blackjack/rhthrhrl0/23-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +253 -0
- package/lessons/woowacourse-kotlin-blackjack/rhthrhrl0/39-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +238 -0
- package/lessons/woowacourse-kotlin-blackjack/rosemin928/129-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +726 -0
- package/lessons/woowacourse-kotlin-blackjack/rosemin928/138-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +845 -0
- package/lessons/woowacourse-kotlin-blackjack/s6m1n/67-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +220 -0
- package/lessons/woowacourse-kotlin-blackjack/s6m1n/99-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +229 -0
- package/lessons/woowacourse-kotlin-blackjack/s9hn/10-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +284 -0
- package/lessons/woowacourse-kotlin-blackjack/sh1mj1/75-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +224 -0
- package/lessons/woowacourse-kotlin-blackjack/songpink/74-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +238 -0
- package/lessons/woowacourse-kotlin-blackjack/songpink/95-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +216 -0
- package/lessons/woowacourse-kotlin-blackjack/sujin9/15-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +132 -0
- package/lessons/woowacourse-kotlin-blackjack/sujin9/47-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +265 -0
- package/lessons/woowacourse-kotlin-blackjack/tmdgh1592/29-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +305 -0
- package/lessons/woowacourse-kotlin-blackjack/tmdgh1592/51-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +278 -0
- package/lessons/woowacourse-kotlin-blackjack/tobae-time/115-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +305 -0
- package/lessons/woowacourse-kotlin-blackjack/tobae-time/154-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +298 -0
- package/lessons/woowacourse-kotlin-blackjack/whk06061/25-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +235 -0
- package/lessons/woowacourse-kotlin-blackjack/whk06061/53-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +130 -0
- package/lessons/woowacourse-kotlin-blackjack/wondroid-world/124-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +486 -0
- package/lessons/woowacourse-kotlin-blackjack/wondroid-world/152-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +482 -0
- package/lessons/woowacourse-kotlin-blackjack/yrsel/120-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +194 -0
- package/lessons/woowacourse-kotlin-blackjack/yrsel/146-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +444 -0
- package/lessons/woowacourse-kotlin-lotto/2chang5/27-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +155 -0
- package/lessons/woowacourse-kotlin-lotto/2chang5/52-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +187 -0
- package/lessons/woowacourse-kotlin-lotto/Choisehyeon/14-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +206 -0
- package/lessons/woowacourse-kotlin-lotto/Choisehyeon/47-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +119 -0
- package/lessons/woowacourse-kotlin-lotto/DYGames/2-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +83 -0
- package/lessons/woowacourse-kotlin-lotto/DYGames/34-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +88 -0
- package/lessons/woowacourse-kotlin-lotto/EmilyCh0/12-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +107 -0
- package/lessons/woowacourse-kotlin-lotto/EmilyCh0/40-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +135 -0
- package/lessons/woowacourse-kotlin-lotto/HANDOVER.md +217 -0
- package/lessons/woowacourse-kotlin-lotto/HamBeomJoon/121-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +66 -0
- package/lessons/woowacourse-kotlin-lotto/HamBeomJoon/139-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +75 -0
- package/lessons/woowacourse-kotlin-lotto/Hevton/76-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +21 -0
- package/lessons/woowacourse-kotlin-lotto/Hevton/92-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +122 -0
- package/lessons/woowacourse-kotlin-lotto/Hogu59/100-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +110 -0
- package/lessons/woowacourse-kotlin-lotto/Hogu59/68-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +84 -0
- package/lessons/woowacourse-kotlin-lotto/JoYehyun99/60-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +176 -0
- package/lessons/woowacourse-kotlin-lotto/JoYehyun99/96-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +71 -0
- package/lessons/woowacourse-kotlin-lotto/Junyoung-WON/61-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +143 -0
- package/lessons/woowacourse-kotlin-lotto/Junyoung-WON/93-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +16 -0
- package/lessons/woowacourse-kotlin-lotto/Leeyerin0210/109-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +57 -0
- package/lessons/woowacourse-kotlin-lotto/Leeyerin0210/135-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +115 -0
- package/lessons/woowacourse-kotlin-lotto/PROGRESS.md +160 -0
- package/lessons/woowacourse-kotlin-lotto/README.md +77 -0
- package/lessons/woowacourse-kotlin-lotto/RightHennessy/32-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +178 -0
- package/lessons/woowacourse-kotlin-lotto/RightHennessy/5-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +149 -0
- package/lessons/woowacourse-kotlin-lotto/SUMMARY.md +369 -0
- package/lessons/woowacourse-kotlin-lotto/SeongHoonC/25-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +129 -0
- package/lessons/woowacourse-kotlin-lotto/SeongHoonC/37-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +27 -0
- package/lessons/woowacourse-kotlin-lotto/Yunseok-Nam/72-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +137 -0
- package/lessons/woowacourse-kotlin-lotto/Yunseok-Nam/86-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +17 -0
- package/lessons/woowacourse-kotlin-lotto/aprilgom/102-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +62 -0
- package/lessons/woowacourse-kotlin-lotto/aprilgom/64-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +146 -0
- package/lessons/woowacourse-kotlin-lotto/boogi-woogi/11-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +26 -0
- package/lessons/woowacourse-kotlin-lotto/boogi-woogi/29-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +26 -0
- package/lessons/woowacourse-kotlin-lotto/briandr97/26-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +52 -0
- package/lessons/woowacourse-kotlin-lotto/briandr97/51-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +123 -0
- package/lessons/woowacourse-kotlin-lotto/chaehyuns/71-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +115 -0
- package/lessons/woowacourse-kotlin-lotto/chaehyuns/97-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +107 -0
- package/lessons/woowacourse-kotlin-lotto/chanho0908/124-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +51 -0
- package/lessons/woowacourse-kotlin-lotto/chanho0908/129-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +149 -0
- package/lessons/woowacourse-kotlin-lotto/chws0508/24-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +117 -0
- package/lessons/woowacourse-kotlin-lotto/chws0508/50-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +167 -0
- package/lessons/woowacourse-kotlin-lotto/cucumber99/116-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +155 -0
- package/lessons/woowacourse-kotlin-lotto/cucumber99/147-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +223 -0
- package/lessons/woowacourse-kotlin-lotto/devfeijoa/125-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +68 -0
- package/lessons/woowacourse-kotlin-lotto/devfeijoa/153-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +107 -0
- package/lessons/woowacourse-kotlin-lotto/doabletuple/119-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +157 -0
- package/lessons/woowacourse-kotlin-lotto/doabletuple/138-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +77 -0
- package/lessons/woowacourse-kotlin-lotto/donghyun81/111-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +67 -0
- package/lessons/woowacourse-kotlin-lotto/donghyun81/152-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +124 -0
- package/lessons/woowacourse-kotlin-lotto/dpcks0509/80-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +141 -0
- package/lessons/woowacourse-kotlin-lotto/dpcks0509/87-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +134 -0
- package/lessons/woowacourse-kotlin-lotto/etama123/112-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +170 -0
- package/lessons/woowacourse-kotlin-lotto/etama123/148-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +183 -0
- package/lessons/woowacourse-kotlin-lotto/gaeun5744/101-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +21 -0
- package/lessons/woowacourse-kotlin-lotto/gaeun5744/78-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +158 -0
- package/lessons/woowacourse-kotlin-lotto/gahyunkim/107-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +83 -0
- package/lessons/woowacourse-kotlin-lotto/gahyunkim/136-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +51 -0
- package/lessons/woowacourse-kotlin-lotto/giovannijunseokim/106-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +171 -0
- package/lessons/woowacourse-kotlin-lotto/giovannijunseokim/137-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +111 -0
- package/lessons/woowacourse-kotlin-lotto/haeum808/67-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +52 -0
- package/lessons/woowacourse-kotlin-lotto/haeum808/95-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +97 -0
- package/lessons/woowacourse-kotlin-lotto/hwannow/113-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +235 -0
- package/lessons/woowacourse-kotlin-lotto/hwannow/132-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +149 -0
- package/lessons/woowacourse-kotlin-lotto/hxeyexn/77-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +141 -0
- package/lessons/woowacourse-kotlin-lotto/hxeyexn/98-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +162 -0
- package/lessons/woowacourse-kotlin-lotto/hyemdooly/17-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +19 -0
- package/lessons/woowacourse-kotlin-lotto/hyemdooly/28-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +23 -0
- package/lessons/woowacourse-kotlin-lotto/hyunji1203/15-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +171 -0
- package/lessons/woowacourse-kotlin-lotto/hyunji1203/48-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +150 -0
- package/lessons/woowacourse-kotlin-lotto/ii2001/62-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +104 -0
- package/lessons/woowacourse-kotlin-lotto/ii2001/88-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +20 -0
- package/lessons/woowacourse-kotlin-lotto/ijh1298/122-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +179 -0
- package/lessons/woowacourse-kotlin-lotto/ijh1298/133-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +153 -0
- package/lessons/woowacourse-kotlin-lotto/inseonyun/3-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +222 -0
- package/lessons/woowacourse-kotlin-lotto/inseonyun/49-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +166 -0
- package/lessons/woowacourse-kotlin-lotto/ippnsj/16-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +154 -0
- package/lessons/woowacourse-kotlin-lotto/ippnsj/55-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +145 -0
- package/lessons/woowacourse-kotlin-lotto/jaeyeongjo/59-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +68 -0
- package/lessons/woowacourse-kotlin-lotto/jaeyeongjo/83-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +53 -0
- package/lessons/woowacourse-kotlin-lotto/jerry8282/115-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +97 -0
- package/lessons/woowacourse-kotlin-lotto/jerry8282/134-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +145 -0
- package/lessons/woowacourse-kotlin-lotto/jinuemong/63-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +144 -0
- package/lessons/woowacourse-kotlin-lotto/jinuemong/89-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +148 -0
- package/lessons/woowacourse-kotlin-lotto/jiyuneel/128-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +52 -0
- package/lessons/woowacourse-kotlin-lotto/jiyuneel/144-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +149 -0
- package/lessons/woowacourse-kotlin-lotto/junjange/58-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +148 -0
- package/lessons/woowacourse-kotlin-lotto/junjange/81-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +178 -0
- package/lessons/woowacourse-kotlin-lotto/junseo511/120-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +153 -0
- package/lessons/woowacourse-kotlin-lotto/junseo511/131-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +188 -0
- package/lessons/woowacourse-kotlin-lotto/ki960213/43-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +24 -0
- package/lessons/woowacourse-kotlin-lotto/ki960213/8-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +159 -0
- package/lessons/woowacourse-kotlin-lotto/kimhm0728/74-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +50 -0
- package/lessons/woowacourse-kotlin-lotto/kimhm0728/94-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +176 -0
- package/lessons/woowacourse-kotlin-lotto/kkosang/85-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +145 -0
- package/lessons/woowacourse-kotlin-lotto/kmkim2689/70-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +97 -0
- package/lessons/woowacourse-kotlin-lotto/kmkim2689/82-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +157 -0
- package/lessons/woowacourse-kotlin-lotto/krrong/19-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +161 -0
- package/lessons/woowacourse-kotlin-lotto/krrong/41-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +73 -0
- package/lessons/woowacourse-kotlin-lotto/m6z1/105-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +67 -0
- package/lessons/woowacourse-kotlin-lotto/m6z1/151-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +104 -0
- package/lessons/woowacourse-kotlin-lotto/medAndro/127-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +186 -0
- package/lessons/woowacourse-kotlin-lotto/medAndro/130-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +132 -0
- package/lessons/woowacourse-kotlin-lotto/moondev03/110-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +66 -0
- package/lessons/woowacourse-kotlin-lotto/moondev03/141-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +155 -0
- package/lessons/woowacourse-kotlin-lotto/murjune/69-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +143 -0
- package/lessons/woowacourse-kotlin-lotto/murjune/90-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +177 -0
- package/lessons/woowacourse-kotlin-lotto/no1msh/20-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +69 -0
- package/lessons/woowacourse-kotlin-lotto/no1msh/46-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +143 -0
- package/lessons/woowacourse-kotlin-lotto/otter66/13-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +178 -0
- package/lessons/woowacourse-kotlin-lotto/otter66/53-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +160 -0
- package/lessons/woowacourse-kotlin-lotto/oungsi2000/126-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +71 -0
- package/lessons/woowacourse-kotlin-lotto/oungsi2000/149-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +56 -0
- package/lessons/woowacourse-kotlin-lotto/parkjiminnnn/117-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +129 -0
- package/lessons/woowacourse-kotlin-lotto/parkjiminnnn/146-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +173 -0
- package/lessons/woowacourse-kotlin-lotto/pingu244/33-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +21 -0
- package/lessons/woowacourse-kotlin-lotto/pingu244/54-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +30 -0
- package/lessons/woowacourse-kotlin-lotto/pingu244/7-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +19 -0
- package/lessons/woowacourse-kotlin-lotto/re4rk/31-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +143 -0
- package/lessons/woowacourse-kotlin-lotto/re4rk/4-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +66 -0
- package/lessons/woowacourse-kotlin-lotto/rhkrwngud445/23-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +26 -0
- package/lessons/woowacourse-kotlin-lotto/rhkrwngud445/38-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +129 -0
- package/lessons/woowacourse-kotlin-lotto/rhthrhrl0/21-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +146 -0
- package/lessons/woowacourse-kotlin-lotto/rhthrhrl0/36-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +150 -0
- package/lessons/woowacourse-kotlin-lotto/rosemin928/123-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +179 -0
- package/lessons/woowacourse-kotlin-lotto/rosemin928/140-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +126 -0
- package/lessons/woowacourse-kotlin-lotto/s6m1n/103-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +119 -0
- package/lessons/woowacourse-kotlin-lotto/s6m1n/66-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +118 -0
- package/lessons/woowacourse-kotlin-lotto/s9hn/18-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +112 -0
- package/lessons/woowacourse-kotlin-lotto/sh1mj1/75-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +104 -0
- package/lessons/woowacourse-kotlin-lotto/sh1mj1/91-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +140 -0
- package/lessons/woowacourse-kotlin-lotto/songpink/65-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +96 -0
- package/lessons/woowacourse-kotlin-lotto/songpink/99-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +64 -0
- package/lessons/woowacourse-kotlin-lotto/sujin9/10-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +20 -0
- package/lessons/woowacourse-kotlin-lotto/sujin9/35-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +124 -0
- package/lessons/woowacourse-kotlin-lotto/tmdgh1592/22-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +30 -0
- package/lessons/woowacourse-kotlin-lotto/tmdgh1592/30-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +20 -0
- package/lessons/woowacourse-kotlin-lotto/tobae-time/114-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +158 -0
- package/lessons/woowacourse-kotlin-lotto/tobae-time/145-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +120 -0
- package/lessons/woowacourse-kotlin-lotto/whk06061/42-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +21 -0
- package/lessons/woowacourse-kotlin-lotto/whk06061/9-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +89 -0
- package/lessons/woowacourse-kotlin-lotto/wondroid-world/118-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +100 -0
- package/lessons/woowacourse-kotlin-lotto/wondroid-world/150-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +142 -0
- package/lessons/woowacourse-kotlin-lotto/yrsel/108-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +124 -0
- package/lessons/woowacourse-kotlin-lotto/yrsel/143-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +108 -0
- package/lessons/woowacourse-racingcar/2chang5/33-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +56 -0
- package/lessons/woowacourse-racingcar/2chang5/75-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +53 -0
- package/lessons/woowacourse-racingcar/CFalws/85-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +56 -0
- package/lessons/woowacourse-racingcar/Choisehyeon/46-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +61 -0
- package/lessons/woowacourse-racingcar/DYGames/49-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +62 -0
- package/lessons/woowacourse-racingcar/EmilyCh0/40-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +64 -0
- package/lessons/woowacourse-racingcar/EmilyCh0/57-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +55 -0
- package/lessons/woowacourse-racingcar/HamBeomJoon/137-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +55 -0
- package/lessons/woowacourse-racingcar/HamBeomJoon/170-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +50 -0
- package/lessons/woowacourse-racingcar/Hevton/106-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +54 -0
- package/lessons/woowacourse-racingcar/Hevton/118-/353/246/254/355/214/251/355/204/260/353/247/201.md +51 -0
- package/lessons/woowacourse-racingcar/Hogu59/108-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +56 -0
- package/lessons/woowacourse-racingcar/Hogu59/125-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +59 -0
- package/lessons/woowacourse-racingcar/JoYehyun99/111-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +57 -0
- package/lessons/woowacourse-racingcar/JoYehyun99/88-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +45 -0
- package/lessons/woowacourse-racingcar/Junyoung-WON/127-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +49 -0
- package/lessons/woowacourse-racingcar/Junyoung-WON/90-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +49 -0
- package/lessons/woowacourse-racingcar/Leeyerin0210/133-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +50 -0
- package/lessons/woowacourse-racingcar/Leeyerin0210/159-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +53 -0
- package/lessons/woowacourse-racingcar/PROGRESS.md +94 -0
- package/lessons/woowacourse-racingcar/README.md +69 -0
- package/lessons/woowacourse-racingcar/RightHennessy/51-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +55 -0
- package/lessons/woowacourse-racingcar/RightHennessy/58-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +57 -0
- package/lessons/woowacourse-racingcar/RunaNam/81-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +44 -0
- package/lessons/woowacourse-racingcar/SUMMARY.md +339 -0
- package/lessons/woowacourse-racingcar/SeongHoonC/37-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +57 -0
- package/lessons/woowacourse-racingcar/SeongHoonC/66-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +48 -0
- package/lessons/woowacourse-racingcar/Songusika/84-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +60 -0
- package/lessons/woowacourse-racingcar/Yunseok-Nam/114-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +43 -0
- package/lessons/woowacourse-racingcar/Yunseok-Nam/96-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +54 -0
- package/lessons/woowacourse-racingcar/aprilgom/130-/353/246/254/355/214/251/355/204/260/353/247/201.md +52 -0
- package/lessons/woowacourse-racingcar/aprilgom/97-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +49 -0
- package/lessons/woowacourse-racingcar/awesomeo184/23-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +48 -0
- package/lessons/woowacourse-racingcar/boogi-woogi/35-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +62 -0
- package/lessons/woowacourse-racingcar/boogi-woogi/59-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +55 -0
- package/lessons/woowacourse-racingcar/briandr97/54-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +57 -0
- package/lessons/woowacourse-racingcar/chaehyuns/131-/353/246/254/355/214/251/355/204/260/353/247/201.md +49 -0
- package/lessons/woowacourse-racingcar/chaehyuns/99-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +52 -0
- package/lessons/woowacourse-racingcar/chanho0908/147-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +54 -0
- package/lessons/woowacourse-racingcar/chanho0908/160-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +50 -0
- package/lessons/woowacourse-racingcar/chws0508/45-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +61 -0
- package/lessons/woowacourse-racingcar/chws0508/73-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +46 -0
- package/lessons/woowacourse-racingcar/cucumber99/132-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +55 -0
- package/lessons/woowacourse-racingcar/cucumber99/177-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +53 -0
- package/lessons/woowacourse-racingcar/devfeijoa/146-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +57 -0
- package/lessons/woowacourse-racingcar/doabletuple/149-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +55 -0
- package/lessons/woowacourse-racingcar/doabletuple/175-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +53 -0
- package/lessons/woowacourse-racingcar/donghyun81/154-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +58 -0
- package/lessons/woowacourse-racingcar/dpcks0509/103-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +48 -0
- package/lessons/woowacourse-racingcar/dpcks0509/112-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +48 -0
- package/lessons/woowacourse-racingcar/drunkenhw/82-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +60 -0
- package/lessons/woowacourse-racingcar/etama123/145-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +59 -0
- package/lessons/woowacourse-racingcar/gaeun5744/124-/353/246/254/355/214/251/355/204/260/353/247/201.md +53 -0
- package/lessons/woowacourse-racingcar/gaeun5744/93-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +60 -0
- package/lessons/woowacourse-racingcar/gahyunkim/134-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +53 -0
- package/lessons/woowacourse-racingcar/gahyunkim/164-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +54 -0
- package/lessons/woowacourse-racingcar/giovannijunseokim/140-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +54 -0
- package/lessons/woowacourse-racingcar/haeum808/101-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +55 -0
- package/lessons/woowacourse-racingcar/haeum808/129-/353/246/254/355/214/251/355/204/260/353/247/201.md +46 -0
- package/lessons/woowacourse-racingcar/hwannow/141-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +56 -0
- package/lessons/woowacourse-racingcar/hwannow/157-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +45 -0
- package/lessons/woowacourse-racingcar/hxeyexn/109-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +61 -0
- package/lessons/woowacourse-racingcar/hxeyexn/128-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +59 -0
- package/lessons/woowacourse-racingcar/hyemdooly/50-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +48 -0
- package/lessons/woowacourse-racingcar/hyemdooly/68-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +53 -0
- package/lessons/woowacourse-racingcar/hyunji1203/29-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +54 -0
- package/lessons/woowacourse-racingcar/hyunji1203/60-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +50 -0
- package/lessons/woowacourse-racingcar/ii2001/102-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +42 -0
- package/lessons/woowacourse-racingcar/ii2001/122-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +49 -0
- package/lessons/woowacourse-racingcar/ijh1298/144-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +57 -0
- package/lessons/woowacourse-racingcar/injoon2019/24-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +58 -0
- package/lessons/woowacourse-racingcar/inseonyun/44-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +60 -0
- package/lessons/woowacourse-racingcar/inseonyun/76-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +53 -0
- package/lessons/woowacourse-racingcar/ippnsj/36-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +54 -0
- package/lessons/woowacourse-racingcar/ippnsj/67-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +57 -0
- package/lessons/woowacourse-racingcar/jaeyeongjo/110-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +39 -0
- package/lessons/woowacourse-racingcar/jaeyeongjo/89-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +46 -0
- package/lessons/woowacourse-racingcar/jinuemong/104-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +49 -0
- package/lessons/woowacourse-racingcar/jinuemong/117-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +42 -0
- package/lessons/woowacourse-racingcar/jiyuneel/142-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +59 -0
- package/lessons/woowacourse-racingcar/junjange/113-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +41 -0
- package/lessons/woowacourse-racingcar/junjange/87-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +39 -0
- package/lessons/woowacourse-racingcar/junseo511/148-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +52 -0
- package/lessons/woowacourse-racingcar/junseo511/165-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +51 -0
- package/lessons/woowacourse-racingcar/ki960213/32-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +55 -0
- package/lessons/woowacourse-racingcar/ki960213/63-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +51 -0
- package/lessons/woowacourse-racingcar/kimhm0728/100-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +52 -0
- package/lessons/woowacourse-racingcar/kimhm0728/116-/353/246/254/355/214/251/355/204/260/353/247/201.md +54 -0
- package/lessons/woowacourse-racingcar/kkosang/105-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +54 -0
- package/lessons/woowacourse-racingcar/kkosang/126-/353/246/254/355/214/251/355/204/260/353/247/201.md +53 -0
- package/lessons/woowacourse-racingcar/kmkim2689/123-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +50 -0
- package/lessons/woowacourse-racingcar/kmkim2689/92-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +55 -0
- package/lessons/woowacourse-racingcar/krrong/34-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +63 -0
- package/lessons/woowacourse-racingcar/m6z1/150-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +53 -0
- package/lessons/woowacourse-racingcar/m6z1/156-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +40 -0
- package/lessons/woowacourse-racingcar/medAndro/153-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +54 -0
- package/lessons/woowacourse-racingcar/moondev03/135-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +57 -0
- package/lessons/woowacourse-racingcar/moondev03/161-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +52 -0
- package/lessons/woowacourse-racingcar/murjune/121-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +50 -0
- package/lessons/woowacourse-racingcar/murjune/95-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +54 -0
- package/lessons/woowacourse-racingcar/no1msh/43-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +55 -0
- package/lessons/woowacourse-racingcar/no1msh/69-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +60 -0
- package/lessons/woowacourse-racingcar/otter66/48-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +53 -0
- package/lessons/woowacourse-racingcar/otter66/77-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +52 -0
- package/lessons/woowacourse-racingcar/oungsi2000/152-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +56 -0
- package/lessons/woowacourse-racingcar/oungsi2000/187-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +54 -0
- package/lessons/woowacourse-racingcar/parkjiminnnn/143-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +58 -0
- package/lessons/woowacourse-racingcar/parkjiminnnn/158-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +54 -0
- package/lessons/woowacourse-racingcar/pingu244/38-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +58 -0
- package/lessons/woowacourse-racingcar/pingu244/62-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +59 -0
- package/lessons/woowacourse-racingcar/re4rk/28-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +60 -0
- package/lessons/woowacourse-racingcar/re4rk/55-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +54 -0
- package/lessons/woowacourse-racingcar/rhkrwngud445/42-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +53 -0
- package/lessons/woowacourse-racingcar/rhkrwngud445/74-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +47 -0
- package/lessons/woowacourse-racingcar/rhthrhrl0/31-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +43 -0
- package/lessons/woowacourse-racingcar/rosemin928/138-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +53 -0
- package/lessons/woowacourse-racingcar/rosemin928/171-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +38 -0
- package/lessons/woowacourse-racingcar/s6m1n/120-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +54 -0
- package/lessons/woowacourse-racingcar/s6m1n/91-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +62 -0
- package/lessons/woowacourse-racingcar/s9hn/53-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +44 -0
- package/lessons/woowacourse-racingcar/s9hn/78-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +43 -0
- package/lessons/woowacourse-racingcar/sh1mj1/107-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +55 -0
- package/lessons/woowacourse-racingcar/sh1mj1/115-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +61 -0
- package/lessons/woowacourse-racingcar/songpink/119-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +51 -0
- package/lessons/woowacourse-racingcar/songpink/98-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +55 -0
- package/lessons/woowacourse-racingcar/sujin9/52-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +48 -0
- package/lessons/woowacourse-racingcar/sujin9/61-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +47 -0
- package/lessons/woowacourse-racingcar/tmdgh1592/47-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +49 -0
- package/lessons/woowacourse-racingcar/tmdgh1592/64-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +53 -0
- package/lessons/woowacourse-racingcar/tobae-time/151-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +51 -0
- package/lessons/woowacourse-racingcar/tobae-time/167-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +43 -0
- package/lessons/woowacourse-racingcar/whk06061/41-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +58 -0
- package/lessons/woowacourse-racingcar/wondroid-world/136-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +49 -0
- package/lessons/woowacourse-racingcar/wondroid-world/166-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +50 -0
- package/lessons/woowacourse-racingcar/yrsel/139-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +53 -0
- package/lessons/woowacourse-racingcar/yujamint/83-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +59 -0
- package/package.json +46 -0
- package/skills/oh-my-oop/SKILL.md +39 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# PR #101 — [로또] 벼리 2단계 미션
|
|
2
|
+
|
|
3
|
+
- **Reviewee:** [@gaeun5744](https://github.com/gaeun5744)
|
|
4
|
+
- **PR:** https://github.com/woowacourse/kotlin-lotto/pull/101
|
|
5
|
+
- **단계:** 2단계
|
|
6
|
+
- **리뷰어:** *(self-discussion)*
|
|
7
|
+
- **라인 코멘트:** 14
|
|
8
|
+
|
|
9
|
+
## 학생 자가 변경 이유
|
|
10
|
+
|
|
11
|
+
> 이전에서는 제가 문자열은 따로 companion object에서 const val로 선언함으로써 한곳에 모아두었지만, 이번 pr에서는 문자열을 그대로 넣었습니다.
|
|
12
|
+
|
|
13
|
+
> 기존에는 `InputView`에 모든 로직을 두었지만, 이번 pr에서는 연관된 함수들을 묶어서 `domain` 객체를 생성한 후에 Controller에 전달하는 방식으로 로직을 세.
|
|
14
|
+
|
|
15
|
+
> `Ticket`이 `lottos`를 발행한다는 상황이 어색해보여서, `lottoMachine`으로 수정했습니다!!
|
|
16
|
+
|
|
17
|
+
## 얻은 교훈
|
|
18
|
+
|
|
19
|
+
- **상수 분리 vs 인라인 = 컨텍스트에 따라**. 1단계에서 모은 상수를 2단계에서 인라인으로 되돌리는 결정도 *왜*가 명확하면 OK.
|
|
20
|
+
- **InputView 분리** — 연관 함수를 도메인 객체로 묶기.
|
|
21
|
+
- **이름이 어색하면 변경** — `Ticket`보다 `LottoMachine`이 *발행* 행위 어울림.
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
# PR #78 — [로또] 벼리 1단계 미션
|
|
2
|
+
|
|
3
|
+
- **Reviewee:** [@gaeun5744](https://github.com/gaeun5744)
|
|
4
|
+
- **PR:** https://github.com/woowacourse/kotlin-lotto/pull/78
|
|
5
|
+
- **단계:** 1단계
|
|
6
|
+
- **리뷰어:** @KwonDae (제이든)
|
|
7
|
+
- **라인 코멘트:** 38
|
|
8
|
+
|
|
9
|
+
## 잘한 점 (설계 관점)
|
|
10
|
+
|
|
11
|
+
- **`LottoPrize` enum에 `(matchingCount, amount)` 결합** — 등수와 상금이 한 곳.
|
|
12
|
+
- **`LottoNumberGenerator` 인터페이스 + `RandomLottoNumberGenerator` 구현** — 랜덤 격리 시도.
|
|
13
|
+
- **`Lotto`의 `numbers`를 `private`로 캡슐화** — 외부에서 `List<LottoNumber>` 접근 차단.
|
|
14
|
+
- **`PurchaseInfo`로 구매 정보 1차 포장** — `price`/`amount`를 객체에.
|
|
15
|
+
- **자가 질문 PR에 풍부히 명시** — 책임 위치, object 사용 여부 등 학생이 먼저 논점 제기.
|
|
16
|
+
|
|
17
|
+
## 못한 점 (설계 관점)
|
|
18
|
+
|
|
19
|
+
### 1. `ModelTest.kt` 단일 파일에 모든 모델 테스트
|
|
20
|
+
|
|
21
|
+
```kotlin
|
|
22
|
+
class ModelTest { /* Lotto, LottoNumber, PurchaseInfo, WinningLotto 모두 */ }
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
리뷰어: "한 테스트 파일에서 모델에 대한 테스트를 전부 진행하고 있네요. 모델이 굉장히 많아진다면 이 테스트 파일도 비대해질 것 같은데요, Model 별로 분리해주세요." — Test 클래스는 SUT당 1:1. `LottoTest`, `LottoNumberTest`, …
|
|
26
|
+
|
|
27
|
+
### 2. `LottoConstants`/`StringConstants` god-folder
|
|
28
|
+
|
|
29
|
+
```kotlin
|
|
30
|
+
object LottoConstants {
|
|
31
|
+
const val LOTTO_SIZE = 6
|
|
32
|
+
const val LOTTO_MIN_NUMBER = 1
|
|
33
|
+
const val LOTTO_MAX_NUMBER = 45
|
|
34
|
+
const val LOTTO_PRICE = 1000
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
object StringConstants {
|
|
38
|
+
const val ERROR_MESSAGE = "[ERROR]"
|
|
39
|
+
const val INVALID_PURCHASE_PRICE = "."
|
|
40
|
+
const val INVALID_LOTTO_NUMBER = "."
|
|
41
|
+
.
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
리뷰어: "object로 분리되는 상수의 기준은 무엇일까요? 지금이야 규모가 작아 상수 관리가 되겠지만 규모가 큰 프로젝트라면 어느 순간 파편화가 될 가능성이 높아보여요. 위 상수들을 대체할 다른 객체 혹은 한정자를 통해 해당 파일에서 관리하도록 수정해볼까요?" — *어떤 상수든 다 들어가는* god-object는 응집도 0. 도메인별 객체의 `companion object`로 배치.
|
|
46
|
+
|
|
47
|
+
### 3. `Lotto.compare(otherLotto, bonusNumber): LottoPrize` — 책임 과부하
|
|
48
|
+
|
|
49
|
+
```kotlin
|
|
50
|
+
fun compare(otherLotto: Lotto, bonusNumber: LottoNumber): LottoPrize {
|
|
51
|
+
val matchingCount = otherLotto.numbers.intersect(numbers).size
|
|
52
|
+
val isMatchingBonus = contains(bonusNumber)
|
|
53
|
+
return LottoPrize.getLottoPrize(matchingCount, isMatchingBonus)
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
문제 1: 함수명 `compare`는 정렬 비교 시그니처. 문제 2: `Lotto`가 `LottoPrize` 결정 책임을 가짐 — 등수 판정은 *당첨 정보(당첨 번호+보너스+규칙)* 의 책임. Lotto는 *매칭 개수만* 반환해야 함.
|
|
58
|
+
|
|
59
|
+
### 4. `WinningLotto`가 검증만 — 책임 부재
|
|
60
|
+
|
|
61
|
+
```kotlin
|
|
62
|
+
class WinningLotto(val lotto: Lotto, val bonusNumber: LottoNumber) {
|
|
63
|
+
init { require(!lotto.contains(bonusNumber)) {. } }
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
리뷰어: "WinningLotto라는 일급컬렉션을 사용해주셨네요. 지금은 값을 wrapping 하는 것 외에는 다른 역할이 없어서 클래스의 존재가 잘 드러나지 않고 있어요. 예를 들어, 당첨 번호 비교, 검증 같은 로직을 여기서 수행해보는 건 어떨까요?" — 후속 리뷰에서 더 강하게: "WinningLotto에서 해당 티켓, 당첨 로또, 보너스번호 위 3개 정보만 알아도 총 당첨 갯수와 수익률 모두 하나의 도메인에서 해결이 가능할 것 같습니다."
|
|
68
|
+
|
|
69
|
+
### 5. `PurchaseInfo`가 `LOTTO_PRICE`를 상수 의존
|
|
70
|
+
|
|
71
|
+
```kotlin
|
|
72
|
+
class PurchaseInfo(purchasePrice: String) {
|
|
73
|
+
val price: Int
|
|
74
|
+
val amount: Int
|
|
75
|
+
init {
|
|
76
|
+
require(. && purchasePrice.isMoreThanMin() && purchasePrice.divideByLottoPrice()) {. }
|
|
77
|
+
amount = price / LOTTO_PRICE
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
리뷰어: "로또 가격이 인상되었다면, `isMoreThanMin`과 같은 비즈니스 로직 내부 코드도 변경되어야 하고 테스트 코드도 변경되어야 합니다." — 학생 의문: "companion object의 `LOTTO_PRICE`를 변경하지 않고 외부에서 변경해야 하는 이유가 궁금합니다!" 리뷰어 답: "추후 기획자의 요구사항에 따라 여러 종류의 복권을 판매하도록 요구사항이 주어진다면, 각 복권마다의 `PurchaseInfo`를 따로 구현해야 할까요?" — 가격은 *외부 주입*해야 다중 복권 대응.
|
|
83
|
+
|
|
84
|
+
### 6. `LottoPrize.getLottoPrize`의 매직넘버 `5`
|
|
85
|
+
|
|
86
|
+
```kotlin
|
|
87
|
+
companion object {
|
|
88
|
+
fun getLottoPrize(matchingCount: Int, isMatchingBonus: Boolean): LottoPrize {
|
|
89
|
+
if (matchingCount == 5) {. } // ⚠ enum 값으로 대체 가능
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
학생 의문: "2등과 3등의 matchingCount가 서로 같아서 SECOND.amount 혹은 THIRD.amount 둘다 사용 가능하기에 그냥 그대로 5를 넣었습니다." 리뷰어: "이 케이스에만 들어맞기 때문에 이 값이 갖는 특별한 의미를 인지하지 못하고, 경계하지 않으면 수정사항에 정상적으로 대응하지 못할 가능성이 크겠죠. 또한, 단위 테스트가 이 문제를 발견하지 못할 수 있다는 것입니다."
|
|
95
|
+
|
|
96
|
+
### 7. `retryWhileNoException`의 위치 — Controller 안
|
|
97
|
+
|
|
98
|
+
```kotlin
|
|
99
|
+
class LottoController {
|
|
100
|
+
private fun <T> retryWhileNoException(action: () -> T): T {
|
|
101
|
+
return try { action() } catch (e: IllegalArgumentException) {
|
|
102
|
+
println("${ERROR_MESSAGE} ${e.localizedMessage}")
|
|
103
|
+
action()
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
리뷰어: "이 함수는 예외 발생시 출력을 하고 있고, 이 함수를 사용하는 함수들의 공통점은 View와 관련이 있다는 겁니다. 그러면 어디에서 관리하는게 보다 가독성이 좋을까요?" — 출력+재시도는 View 인접 책임. *함수가 어디서 *호출되는가*가 아니라 *무엇과 협력하는가*가 위치 기준.
|
|
110
|
+
|
|
111
|
+
### 8. `object InputView`/`OutputView` — 메모리 vs 책임
|
|
112
|
+
|
|
113
|
+
학생 결정: "InputView는 지속적으로 사용하는 클래스가 아닌, 뷰 로직에서만 사용하기 때문에 프로그램 런타임 내내 메모리를 차지하는 것은 낭비라는 생각이 들었습니다!" 리뷰어 반박: "Controller 뿐 아니라 많은 곳에서도 InputView, OutputView를 사용해야 하는 상황이라면 어떻게 생각하시나요?" — `object` 결정 기준은 *메모리*가 아니라 *상태/인스턴스화 필요성*.
|
|
114
|
+
|
|
115
|
+
### 9. `WinningStatics`가 별도 클래스로 분리
|
|
116
|
+
|
|
117
|
+
```kotlin
|
|
118
|
+
class WinningStatics {
|
|
119
|
+
fun calculateProfitRatio(purchaseInfo: PurchaseInfo, prizeCount: Map<LottoPrize, Int>): Double {. }
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
학생 변명: "calculateProfitRatio를 WinningLotto에 넣을 경우 파라미터 3개가 필요해 복잡해짐. 두 객체가 서로 의존하지 않도록 따로 만들었습니다." 리뷰어: "purchaseInfo는 어떤 역할을 하는 클래스일까요? val lottoPrice: Int 프로퍼티의 쓰임새를 한번 생각해볼까요. … 결국 *티켓 = 사용자가 구매한 로또의 정보 집합 & 총 구매 가격*. 그리고 그 티켓의 가격이 있는 Domain이 존재한다면, WinningLotto에서 해당 티켓, 당첨 로또, 보너스번호 위 3개 정보만 알아도 총 당첨 갯수와 수익률 모두 하나의 도메인에서 해결이 가능할 것 같습니다." — 책임이 흩어진 원인은 *Ticket이라는 자연스러운 객체의 부재*.
|
|
124
|
+
|
|
125
|
+
## 리뷰어 의견 요지
|
|
126
|
+
|
|
127
|
+
1. **상수 god-folder = 응집도 0** — 도메인별 객체 안의 `companion object`로.
|
|
128
|
+
2. **`WinningLotto`는 당첨 발표의 *주체*** — 검증만 하는 wrapper는 *객체로서 존재 이유 부재*.
|
|
129
|
+
3. **`Ticket` 같은 *자연스러운 객체*가 빠지면 책임이 흘러넘침** — `WinningStatics`가 *별도로* 생긴 이유는 Ticket이 없어서.
|
|
130
|
+
4. **함수 위치 = *협력 대상*과의 거리** — `retryWhileNoException`이 View 출력 + View 입력과 협력하면 View 옆.
|
|
131
|
+
5. **`object` 결정은 *상태/인스턴스화 필요성*** — 메모리 절약은 부차적, 의미적 기준이 우선.
|
|
132
|
+
6. **매직넘버는 *케이스 안에서 우연히 같은 값*** — `SECOND.matchingCount`처럼 의미가 함께 옮겨가야 변경에 안전.
|
|
133
|
+
7. **PurchaseInfo의 *로또 가격 의존성*은 외부 주입** — 확장(다중 복권) 시 핵심.
|
|
134
|
+
|
|
135
|
+
- **대표 인용:**
|
|
136
|
+
> object로 분리되는 상수의 기준은 무엇일까요? … 위 상수들을 대체할 다른 객체 혹은 한정자를 통해 해당 파일에서 관리하도록 수정해볼까요?
|
|
137
|
+
> — @KwonDae on `src/main/kotlin/lotto/constants/LottoConstants.kt`
|
|
138
|
+
|
|
139
|
+
> WinningLotto라는 일급컬렉션을 사용해주셨네요. 지금은 값을 wrapping 하는 것 외에는 다른 역할이 없어서 클래스의 존재가 잘 드러나지 않고 있어요.
|
|
140
|
+
> — @KwonDae on `src/main/kotlin/lotto/model/WinningLotto.kt`
|
|
141
|
+
|
|
142
|
+
> 결국 *티켓 = 사용자가 구매한 로또의 정보 집합 & 총 구매 가격*. 그리고 그 티켓의 가격이 있는 Domain이 존재한다면, WinningLotto에서 해당 티켓, 당첨 로또, 보너스번호 위 3개 정보만 알아도 총 당첨 갯수와 수익률 모두 하나의 도메인에서 해결이 가능할 것 같습니다.
|
|
143
|
+
> — @KwonDae on `src/main/kotlin/lotto/service/WinningStatics.kt`
|
|
144
|
+
|
|
145
|
+
> 이 함수는 예외 발생시 출력을 하고 있고, 이 함수를 사용하는 함수들의 공통점은 View와 관련이 있다는 겁니다. 그러면 어디에서 관리하는 게 보다 가독성이 좋을까요?
|
|
146
|
+
> — @KwonDae on `src/main/kotlin/lotto/controller/LottoController.kt`
|
|
147
|
+
|
|
148
|
+
## 얻은 교훈
|
|
149
|
+
|
|
150
|
+
- **상수 god-folder는 응집도 0**. `LottoConstants`, `StringConstants` 같이 *어떤 상수든 다*가 기준이면 변경 시 영향 범위가 흩어진다. 도메인별 `companion object`로 가두면 변경 영향이 한 곳에.
|
|
151
|
+
- **Test 클래스는 SUT 1:1**. `ModelTest`는 god-test — 책임 분리의 *테스트* 거울. 모델별 테스트로 쪼개야 실패 메시지가 가리키는 곳이 명확.
|
|
152
|
+
- **검증만 하는 wrapper는 객체가 아니다**. `WinningLotto`가 init 검증만 한다면 `data class`로 충분 — 그러나 *당첨 발표의 주체*로서 `calculatePrizeCount`, `calculateProfitRatio`를 가지면 비로소 객체.
|
|
153
|
+
- **빠진 *자연스러운 도메인 객체*가 책임 분산의 원인**. `WinningStatics`가 *별도* 클래스로 떨어진 까닭은 `Ticket`이라는 *자연어 객체*가 없어서. 자연어로 이름이 떠오르는 객체부터 찾아라.
|
|
154
|
+
- **함수 위치 = 협력 대상과의 거리**. `retryWhileNoException`이 *View 출력 + View 입력*과 협력하면 View 옆. *어디서 호출되는가*가 아니라 *무엇을 알아야 하는가*.
|
|
155
|
+
- **`object` 결정 기준은 *상태/인스턴스화 의도*** — 메모리는 부차적. 상태가 없고 단 하나의 의미라면 `object`로 의미 단언.
|
|
156
|
+
- **매직넘버는 *지금 안 들킴*이 가장 위험**. `5`가 `SECOND.matchingCount`와 같은 의미라면 그렇게 부르고, 다르면 다른 상수로. *우연한 같음*이 변경 시 폭탄.
|
|
157
|
+
- **상수 의존을 외부 주입으로 끌어올리면 다중 사례 대응 가능**. `PurchaseInfo(price: Int, lottoPrice: Int)` — 복권 종류가 늘어도 같은 객체로 처리.
|
|
158
|
+
- **`Tell, Don't Ask`는 비교 책임에도 적용**. `Lotto.compare(other, bonus)`로 LottoPrize까지 결정하면 Lotto가 *판정 규칙*까지 흡수. Lotto는 *매칭 개수*만, 판정은 `WinningLotto`/`LottoPrize`.
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# PR #107 — [로또 1단계] 조이 미션
|
|
2
|
+
|
|
3
|
+
- **Reviewee:** [@gahyunkim](https://github.com/gahyunkim)
|
|
4
|
+
- **PR:** https://github.com/woowacourse/kotlin-lotto/pull/107
|
|
5
|
+
- **단계:** 1단계
|
|
6
|
+
- **리뷰어:** @hyemdooly
|
|
7
|
+
- **라인 코멘트:** 53
|
|
8
|
+
|
|
9
|
+
## 잘한 점 (설계 관점)
|
|
10
|
+
|
|
11
|
+
- **`LottoFactory`로 생성 책임 분리**.
|
|
12
|
+
- **메시지 전달 시도 — Lotto에게 메시지** 칭찬 받음.
|
|
13
|
+
|
|
14
|
+
## 못한 점 (설계 관점)
|
|
15
|
+
|
|
16
|
+
### 1. `Lotto`가 자체 LottoNumber 범위 검증
|
|
17
|
+
|
|
18
|
+
```kotlin
|
|
19
|
+
class Lotto(val numbers: List<Int>) {
|
|
20
|
+
init { require(numbers.all { it in 1..45 }) } // ⚠ 로또 숫자 범위가 Lotto의 책임?
|
|
21
|
+
}
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
> 로또 숫자 범위에 대한 책임은 로또일까요, 로또 숫자일까요?
|
|
25
|
+
|
|
26
|
+
→ `LottoNumber` 객체로 분리하면 그 책임이 자연스럽게 옮겨감.
|
|
27
|
+
|
|
28
|
+
### 2. `bonusNumber: String` — 타입 불일치
|
|
29
|
+
|
|
30
|
+
```kotlin
|
|
31
|
+
class WinningLotto(val lotto: Lotto, val bonusNumber: String) {. }
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
> `bonusNumber`는 왜 `String`이 됐을까요?!
|
|
35
|
+
|
|
36
|
+
→ 입력 파싱이 도메인까지 흘러옴. 도메인은 *파싱된 값*.
|
|
37
|
+
|
|
38
|
+
### 3. `Purchase`도 String
|
|
39
|
+
|
|
40
|
+
```kotlin
|
|
41
|
+
class Purchase(val amount: String) {. }
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
> 구입 금액을 `String`으로 하신 이유가 있으신가요?
|
|
45
|
+
|
|
46
|
+
→ 같은 패턴. 도메인은 Int.
|
|
47
|
+
|
|
48
|
+
### 4. 테스트 코드 반복 — Fake Constructor 미사용
|
|
49
|
+
|
|
50
|
+
```kotlin
|
|
51
|
+
val lotto1 = Lotto(listOf(1, 2, 3, 4, 5, 6))
|
|
52
|
+
val lotto2 = Lotto(listOf(7, 8, 9, 10, 11, 12))
|
|
53
|
+
//. 반복
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
> `Lotto(listOf(1, 2, 3, 4, 5, 6)`로 비슷한 코드가 반복되네요!ㅎㅎ 테스트 코드의 가독성을 좋게 하기 위해, 가짜 생성자를 고려해볼 수 있답니다.
|
|
57
|
+
|
|
58
|
+
### 5. 두 컬렉션 교집합 함수 미활용
|
|
59
|
+
|
|
60
|
+
```kotlin
|
|
61
|
+
val matched = lotto.numbers.filter { it in winning.numbers }
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
> 두 컬렉션 간의 교집합을 구할 수 있는 함수가 있어요. 한번 찾아볼까요?
|
|
65
|
+
|
|
66
|
+
→ `lotto.numbers intersect winning.numbers`.
|
|
67
|
+
|
|
68
|
+
### 6. Factory에 private 미적용
|
|
69
|
+
|
|
70
|
+
```kotlin
|
|
71
|
+
class LottoFactory {
|
|
72
|
+
fun createOne(): Lotto =. // ⚠ 내부에서만 쓰는데 public
|
|
73
|
+
val MIN = 1 // ⚠ public 상수
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
> 이 함수는 내부에서만 사용하고 있어요. `private`으로 닫는 것은 어떨까요?
|
|
78
|
+
|
|
79
|
+
## 얻은 교훈
|
|
80
|
+
|
|
81
|
+
- **String → Int 타입 변환은 *입력 경계*에서 끝**. 도메인이 String 받기 시작하면 *전체 도메인이 파싱 부담*.
|
|
82
|
+
- **`intersect` 컬렉션 함수** — 두 컬렉션 공통 원소. lotto 매칭에 자연스러움.
|
|
83
|
+
- **Factory의 내부 함수는 private** — 노출 면적 최소화.
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# PR #136 — [로또 2단계] 조이 미션
|
|
2
|
+
|
|
3
|
+
- **Reviewee:** [@gahyunkim](https://github.com/gahyunkim)
|
|
4
|
+
- **PR:** https://github.com/woowacourse/kotlin-lotto/pull/136
|
|
5
|
+
- **단계:** 2단계
|
|
6
|
+
- **리뷰어:** @hyemdooly
|
|
7
|
+
- **라인 코멘트:** 45
|
|
8
|
+
|
|
9
|
+
## 잘한 점
|
|
10
|
+
|
|
11
|
+
- **LottoNumber 캐싱 전략** — 칭찬.
|
|
12
|
+
|
|
13
|
+
## 못한 점 + 핵심 지적
|
|
14
|
+
|
|
15
|
+
### 1. 두 `amount` 검증을 Validator가 직접
|
|
16
|
+
|
|
17
|
+
```kotlin
|
|
18
|
+
class Validator {
|
|
19
|
+
fun validate(amount1: Int, amount2: Int) {. } // ⚠ 원시값 검증
|
|
20
|
+
}
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
> amount는 원시값 포장하지 않아도 될까요?
|
|
24
|
+
|
|
25
|
+
→ `PurchaseAmount`, `ManualCount` 같은 값 객체. 외부 Validator 대신 각자 init 검증.
|
|
26
|
+
|
|
27
|
+
### 2. `amount` 네이밍 — 가격 vs 장수 혼동
|
|
28
|
+
|
|
29
|
+
```kotlin
|
|
30
|
+
class Purchase(val amount: Int) {. } // amount가 장수? 금액?
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
> 로또 장수를 `amount`로 네이밍하게 되면서, 이 변수는 가격이라는 의미가 담긴 이름이 더 적절하지 않을까? 생각이 듭니다!
|
|
34
|
+
|
|
35
|
+
### 3. `LottoFactory`가 단순 통과
|
|
36
|
+
|
|
37
|
+
```kotlin
|
|
38
|
+
class LottoFactory(.) {
|
|
39
|
+
fun create(lottos: List<Lotto>): List<Lotto> = lottos // ⚠ 그대로 반환
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
> 로또들을 받아서 그대로 리턴하고 있네요
|
|
44
|
+
|
|
45
|
+
→ Factory가 *생성*도 *변환*도 안 함 = 죽은 추상.
|
|
46
|
+
|
|
47
|
+
## 얻은 교훈
|
|
48
|
+
|
|
49
|
+
- **원시 amount 두 개 = 두 도메인 값 객체로** — Validator 외부화 회피.
|
|
50
|
+
- **`amount` 모호** — 가격이면 `price`, 장수면 `count`. 도메인 어휘.
|
|
51
|
+
- **죽은 추상 회피** — Factory가 통과만 하면 제거.
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
# PR #106 — [로또 1단계] 지오 미션 제출합니다
|
|
2
|
+
|
|
3
|
+
- **Reviewee:** [@giovannijunseokim](https://github.com/giovannijunseokim)
|
|
4
|
+
- **PR:** https://github.com/woowacourse/kotlin-lotto/pull/106
|
|
5
|
+
- **단계:** 1단계
|
|
6
|
+
- **리뷰어:** @hyemdooly
|
|
7
|
+
- **라인 코멘트:** 75
|
|
8
|
+
|
|
9
|
+
## 잘한 점 (설계 관점)
|
|
10
|
+
|
|
11
|
+
- **`LottoResult` enum + `BonusMatched` 별도 enum** — boolean 대신 enum으로 3 상태 (`YES/NO/IRRELEVANT`) 명시.
|
|
12
|
+
- **`LottoNumber` 값 객체 도입**.
|
|
13
|
+
- **PR 본문에 자가 의문 명시** — "접근할 수 없는 부분 테스트?", "when 가독성?".
|
|
14
|
+
- **에러 메시지 케이스별 상수**.
|
|
15
|
+
|
|
16
|
+
## 못한 점 (설계 관점)
|
|
17
|
+
|
|
18
|
+
### 1. Controller가 mutable `lateinit var` 보유
|
|
19
|
+
|
|
20
|
+
```kotlin
|
|
21
|
+
class LottoController {
|
|
22
|
+
lateinit var winningLotto: WinningLotto
|
|
23
|
+
lateinit var boughtLottos: Lottos
|
|
24
|
+
|
|
25
|
+
fun buyLottos() {. }
|
|
26
|
+
fun readWinningLotto() {. }
|
|
27
|
+
fun showResult() {. }
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
> 외부에 열려있어 수정될 위험이 있겠어요. `private`로 막아주면 어떨까요?
|
|
32
|
+
|
|
33
|
+
→ `lateinit var` + public = 상태가 외부에서 변경 가능 + 사용 순서 강제 어려움.
|
|
34
|
+
|
|
35
|
+
### 2. Application과 Controller 분리 의미?
|
|
36
|
+
|
|
37
|
+
```kotlin
|
|
38
|
+
fun main() {
|
|
39
|
+
val lottoApplication = LottoApplication()
|
|
40
|
+
lottoApplication.run()
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
class LottoApplication {
|
|
44
|
+
val controller = LottoController()
|
|
45
|
+
fun run() {
|
|
46
|
+
controller.buyLottos()
|
|
47
|
+
controller.readWinningLotto()
|
|
48
|
+
controller.showResult()
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
> `Application`과 `Controller`의 역할이 나눠진 이유가 있을까요?
|
|
54
|
+
|
|
55
|
+
→ 둘 다 흐름 제어. 분리의 정당화가 약하면 하나로.
|
|
56
|
+
|
|
57
|
+
### 3. `LottoResult` 순서에 의존
|
|
58
|
+
|
|
59
|
+
```kotlin
|
|
60
|
+
companion object {
|
|
61
|
+
fun of(matchCount: Int, bonusMatched: Boolean): LottoResult {
|
|
62
|
+
return values()[matchCount] // ⚠ enum 선언 순서에 의존
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
> 만약 `LottoResult` 상수들이 순서가 바뀐다면 이 코드는 어떻게 될까요?
|
|
68
|
+
|
|
69
|
+
→ enum 선언 순서가 *암묵적 계약*이 되어 버림. 매칭 조건으로 명시적 검색.
|
|
70
|
+
|
|
71
|
+
### 4. 최소 구입 금액 검증이 `Lottos`에
|
|
72
|
+
|
|
73
|
+
```kotlin
|
|
74
|
+
class Lottos(val lottos: List<Lotto>) {
|
|
75
|
+
init {
|
|
76
|
+
require(.) { "최소 구입 금액." } // ⚠ 컬렉션이 금액 정책 검증
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
> 최소 구입 금액에 대한 검증은 `Lottos`의 책임일까요?
|
|
82
|
+
|
|
83
|
+
→ `PurchaseAmount`/`Money` 같은 금액 도메인의 책임.
|
|
84
|
+
|
|
85
|
+
### 5. `Lottos`가 구매 장수 계산까지
|
|
86
|
+
|
|
87
|
+
```kotlin
|
|
88
|
+
class Lottos {
|
|
89
|
+
fun calculate(price: Int): Int =. // ⚠ 가격으로 장수 계산
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
> 가격을 받아서 계산하다보니, 이 함수에서 로또의 장수를 계산하는 역할까지 하고 있어요.
|
|
94
|
+
|
|
95
|
+
→ 구매 장수 계산은 금액 도메인 (`PurchaseAmount.numberOfLottos`).
|
|
96
|
+
|
|
97
|
+
### 6. `LottoNumber`를 매번 새 인스턴스로
|
|
98
|
+
|
|
99
|
+
```kotlin
|
|
100
|
+
val numbers = (1..45).map { LottoNumber(it) } // ⚠ 100개 로또면 100*6 = 600개 인스턴스
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
> 만약 100개, 1000개 이상의 로또 숫자를 생성한다면 어떨까요? 인스턴스 100개, 1000개가 필요할까요?
|
|
104
|
+
|
|
105
|
+
→ 1-45 범위의 LottoNumber는 *고정된 45개*. 캐싱/팩토리 메서드로 재사용.
|
|
106
|
+
|
|
107
|
+
```kotlin
|
|
108
|
+
class LottoNumber private constructor(val value: Int) {
|
|
109
|
+
companion object {
|
|
110
|
+
private val cache = (1..45).associateWith { LottoNumber(it) }
|
|
111
|
+
fun of(value: Int): LottoNumber = cache[value] ?: throw IllegalArgumentException(.)
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### 7. `get()` 커스텀 프로퍼티 vs 함수의 기준 모호
|
|
117
|
+
|
|
118
|
+
```kotlin
|
|
119
|
+
val numberOfLottos: Int get() =. // 또는 fun numberOfLottos(): Int
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
> `get()` 커스텀 프로퍼티를 사용하는 것과, 함수를 사용하는 것, 이 두 가지는 어떨 때 각각 사용할까요?
|
|
123
|
+
|
|
124
|
+
→ Kotlin 컨벤션: 상태 조회/단순 계산은 property, 부수효과/연산 비용 있는 건 함수.
|
|
125
|
+
|
|
126
|
+
### 8. 학생의 자가 의문 — 도달 불가 코드 테스트
|
|
127
|
+
|
|
128
|
+
```kotlin
|
|
129
|
+
companion object {
|
|
130
|
+
fun of(matchCount: Int, bonusMatched: Boolean): LottoResult {
|
|
131
|
+
if (matchCount < FIFTH.matchCount) return FAIL
|
|
132
|
+
//. 매칭.
|
|
133
|
+
throw IllegalArgumentException(.) // ⚠ 도달 불가지만 컴파일러가 모름
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
PR 본문: *"throw에 대한 검증(assertThrow)이 진행되지 않았다고 나오는 것을 확인했습니다."*
|
|
139
|
+
|
|
140
|
+
→ **답:** 도달 불가 코드의 테스트 커버리지는 무의미. 그 코드 자체를 제거하거나, sealed로 컴파일러가 알게 하기.
|
|
141
|
+
|
|
142
|
+
## 리뷰어 의견 요지
|
|
143
|
+
|
|
144
|
+
리뷰어 @hyemdooly의 가르침:
|
|
145
|
+
|
|
146
|
+
1. **lateinit var + public 회피** — private 적용 + 가능하면 생성자 주입.
|
|
147
|
+
|
|
148
|
+
2. **enum의 *순서 의존* 회피** — `values()[index]`는 silent bug 위험. 명시적 매칭으로.
|
|
149
|
+
|
|
150
|
+
3. **금액 도메인의 책임** — Lottos가 금액 검증/계산까지 가지면 god-object 시작.
|
|
151
|
+
|
|
152
|
+
4. **인스턴스 재사용 압박 시뮬레이션** — 1000개로 늘면 부담? 캐싱 검토.
|
|
153
|
+
|
|
154
|
+
5. **이름 설계 시 *함수 vs property* 의식**.
|
|
155
|
+
|
|
156
|
+
- **대표 인용:**
|
|
157
|
+
> 만약 `LottoResult` 상수들이 순서가 바뀐다면 이 코드는 어떻게 될까요?
|
|
158
|
+
>
|
|
159
|
+
> — @hyemdooly on `src/main/kotlin/lotto/controller/LottoController.kt`
|
|
160
|
+
|
|
161
|
+
> 만약 100개, 1000개 이상의 로또 숫자를 생성한다면 어떨까요? 인스턴스 100개, 1000개가 필요할까요?
|
|
162
|
+
>
|
|
163
|
+
> — @hyemdooly on `src/main/kotlin/lotto/domain/LottoNumber.kt`
|
|
164
|
+
|
|
165
|
+
## 얻은 교훈
|
|
166
|
+
|
|
167
|
+
- **enum의 *순서 의존*은 silent bug**. `values()[N]`은 enum 재배치 시 다른 값을 반환 — 컴파일러 경고도 없음. 명시적 `find {. }`로.
|
|
168
|
+
- **고정 범위의 값 객체는 캐싱 후보**. LottoNumber(1-45)는 시스템 전체에서 45개만 존재 = `flyweight` 패턴 후보.
|
|
169
|
+
- **`Lottos`(일급 컬렉션)는 컬렉션 관리만**. 금액, 등수, 통계 같은 부수 도메인은 별도 객체.
|
|
170
|
+
- **도달 불가 코드의 테스트 커버리지 ≠ 신뢰**. 도달 불가하면 *코드 자체를 제거*. sealed class로 컴파일러가 보장하게.
|
|
171
|
+
- **lateinit var = invariant 시간차 파괴**. 객체가 생성 시점부터 *완성된 상태*를 갖도록.
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# PR #137 — [지오] 2단계 로또
|
|
2
|
+
|
|
3
|
+
- **Reviewee:** [@giovannijunseokim](https://github.com/giovannijunseokim)
|
|
4
|
+
- **PR:** https://github.com/woowacourse/kotlin-lotto/pull/137
|
|
5
|
+
- **단계:** 2단계 (수동 로또)
|
|
6
|
+
- **리뷰어:** @hyemdooly (구두)
|
|
7
|
+
- **라인 코멘트:** 24 (리뷰어 17 + 학생 7)
|
|
8
|
+
|
|
9
|
+
## 잘한 점 (설계 관점)
|
|
10
|
+
|
|
11
|
+
- **`LottoShop`이 Generator에게 생성 위임** — Tell-Don't-Ask 칭찬.
|
|
12
|
+
- **`null`을 활용한 예외 처리** — 칭찬: "*null을 활용해서 예외 처리* 👍".
|
|
13
|
+
- **`kdoc` 활용** — 칭찬: "kdoc 활용 👍".
|
|
14
|
+
- **`LottoMachine` 외부 받기** — 후속 리팩토링에서 *방법 주입*.
|
|
15
|
+
|
|
16
|
+
## 못한 점 (설계 관점)
|
|
17
|
+
|
|
18
|
+
### 1. *Controller에서 직접 생성*
|
|
19
|
+
|
|
20
|
+
리뷰어: "*Controller에서 생성하지 않고 밖에서 생성된 것을 받아서 사용할 수* 있을까요?" — DI 권유.
|
|
21
|
+
|
|
22
|
+
### 2. *테스트용 가짜 생성자 프로덕션 코드에*
|
|
23
|
+
|
|
24
|
+
```kotlin
|
|
25
|
+
class Lotto {
|
|
26
|
+
constructor(vararg numbers: Int) : this(numbers.map { LottoNumber(it) }.toSet()) // ⚠ 테스트용
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
리뷰어: "*테스트를 위한 가짜 생성자라면 테스트 코드에 있는 것이 좋을 것 같*아요!" — *프로덕션 코드 오염* 회피.
|
|
31
|
+
|
|
32
|
+
### 3. `RandomLottoGenerator` *생성된 로또 내용 테스트 불가*
|
|
33
|
+
|
|
34
|
+
리뷰어: "로또 머신에게 로또를 생성하는 방법을 알려주고, 그 방법대로 생산하게 하는 것이 좋네요 👍 *테스트하기 쉬워지려면 어떻게 수정해야 할까요? 지금으로서는 RandomLottoGenerator 때문에 생성된 로또의 내용까지는 테스트하기가 어렵겠*군요 🤔" + "*로또 내용 테스트는 LottoShop이 아닌 LottoMachine이나 LottoGenerator가 되어야 겠*군요. *제가 놓쳤어요*!! 감사합니다.ㅎㅎ" — *책임 단위 테스트*.
|
|
35
|
+
|
|
36
|
+
### 4. *테스트 검증부 하드코딩 vs 계산*
|
|
37
|
+
|
|
38
|
+
리뷰어: "제가 *[테스트 검증부 하드코딩](https://jojoldu.tistory.com/615)에 관한 글을 공유*해 드렸던가요? *저는 계산 로직이 직접적으로 들어가는 것보다는 하드코딩을 선호*해요. *지오 생각은 어떠신가요*?" + 후속: "저는 *expect에는 되도록 하드코딩하는 편*입니다! 원래는 지오와 같은 의견으로, *이렇게 작성해야 로또 가격이 변해도 테스트 코드는 잘 돌아간다고 생각*했는데요. *테스트 코드는 일종의 문서이기도 하니, 한 눈에 볼 수 있도록 하드코딩하는 것을 더 선호*하게 되었습니다! 만약 *로또 가격이 변한다면 테스트 코드도 같이 변경*해 줘야 한다고 생각해요. *지금 같은 경우에는 999 이런 식으로요*!" — *테스트 = 문서*: PR #147 (lee-ji-hoon) `var price` 동어 반복과 같은 결.
|
|
39
|
+
|
|
40
|
+
### 5. `winLotto` 변수명
|
|
41
|
+
|
|
42
|
+
리뷰어: "*winLotto에서 win이 된 이유*가 있을까요? 앞에 *boughtLottos*가 있어서 *기존처럼 winLotto가 더 구분하기 좋아 보여서요*!"
|
|
43
|
+
|
|
44
|
+
### 6. *논리적 오류 vs null 반환* — 학생 README 적었음
|
|
45
|
+
|
|
46
|
+
리뷰어: "이번 로또에서 *예외 처리보다는 객체 간의 책임과 역할에 대해 좀 더 리뷰를 드리려고 하고 있긴 한데요*! *README에 '논리적인 오류가 아니면 예외를 던지지 말고 null을 반환한다.' 내용을 적어 주셔서요*.ㅎㅎ *지금은 모든 오류에 대해 예외를 던지고* 있는 것 같아요. *논리적인 오류는 무엇일까요? null을 반환받으면 어떻게 예외 처리를 할 수 있을까요*?" 후속: "*모든 오류가 예외를 던지고 있어서 드린 리뷰였는데, 적절히 수정해 주셨군요* ㅎㅎ 👍".
|
|
47
|
+
|
|
48
|
+
### 7. `LottoShop`이 *처음부터* 손님의 돈+수동 양 보유?
|
|
49
|
+
|
|
50
|
+
리뷰어: "*LottoShop에서 손님의 돈과, 수동으로 구입할 양을 처음부터 들고 있기 보다는 로또를 살 때 받는 게 더 자연*스럽지 않을까 싶은데, *지오 생각은 어떠신가요*?" 학생 후속: *Count 원시값 포장 + 살 때 계산* 두 의견 제시. 리뷰어: "*하지만 지금 요구사항에서는 지오의 의견을 읽어보니 이해가* 되네요! 💭" — *대화로 결정*.
|
|
51
|
+
|
|
52
|
+
### 8. *에러 메시지 sealed class*
|
|
53
|
+
|
|
54
|
+
리뷰어: "이런 에러 메시지를 *sealed class를 활용해서, InputView에서 전달해 줄 수 있을 것* 같아요!" — *상태별 메시지 매핑*.
|
|
55
|
+
|
|
56
|
+
### 9. `interface` vs `fun interface`
|
|
57
|
+
|
|
58
|
+
리뷰어: "*인터페이스에 함수가 하나밖에 없군요! interface vs fun interface에 대해 학습*해 보세요.ㅎㅎ" + "추가로 *LottoGenerator인데, 실제 코드는 LottosGenerator인 것* 같아요. 아마 수동 경우 때문에 이렇게 된 것 같은데, 다른 리뷰에서 같이 코멘트 드리겠습니다!" — *SAM = fun interface*. *Lotto vs Lottos* 시그니처 일관성.
|
|
59
|
+
|
|
60
|
+
### 10. `LottoMachine` *함수형 인터페이스 + View 람다*
|
|
61
|
+
|
|
62
|
+
리뷰어: "*LottoMachine도 외부로부터 받아서 사용하면 어떨까요*? 지금은 하나의 로또 머신이 방법을 주입받아서 사용하고 있는데, *자동 로또 머신과 수동 로또 머신으로 나눠볼 수도 있을 것 같*아요. 즉, *LottoMachine을 만들 때 generator를 주입받는 방법도 있을 것 같*아요!
|
|
63
|
+
|
|
64
|
+
그럼, *사용자한테 입력받는 경우에는 어떻게 처리하나요? 라는 질문*이 있을 것 같은데요.
|
|
65
|
+
```kotlin
|
|
66
|
+
val manualLottoGenerator = LottoGenerator { view.readManualLotto() } // Manual Lotto 하나를 읽어오는 뷰 로직
|
|
67
|
+
```
|
|
68
|
+
이런 식으로 *Controller에서 Generator한테 뷰의 로직을 넘겨줄 수* 있습니다.
|
|
69
|
+
|
|
70
|
+
> 그럼 이건 Domain 입장에서 View를 알고 있는 것은 아닌가요?
|
|
71
|
+
|
|
72
|
+
이 의문에 대해서는 *크루들과 함께 토론*해 보시면 좋을 것 같아요!" — *함수형 인터페이스 람다*로 *책임 전달*. *추상화 깊이* 학생 사고 유도.
|
|
73
|
+
|
|
74
|
+
## 리뷰어 의견 요지
|
|
75
|
+
|
|
76
|
+
- **Controller *직접 생성 X*** — 외부 주입.
|
|
77
|
+
- **테스트 *fake = 테스트 코드*에**.
|
|
78
|
+
- **테스트하기 어려운 곳 = *책임 분리* 신호**.
|
|
79
|
+
- **테스트 *expect 하드코딩***.
|
|
80
|
+
- **변수명 *대조*** — `winLotto` vs `winnings`.
|
|
81
|
+
- **논리적 오류 vs *null 반환***.
|
|
82
|
+
- **`Shop` *살 때 받기*** = 자연 흐름.
|
|
83
|
+
- **에러 메시지 *sealed class* InputView에 매핑**.
|
|
84
|
+
- **`fun interface` *SAM 학습***.
|
|
85
|
+
- **`LottoGenerator { view.readManualLotto() }` *람다로 View 책임 주입*** — *추상화 토론 거리*.
|
|
86
|
+
|
|
87
|
+
- **대표 인용:**
|
|
88
|
+
> 테스트하기 쉬워지려면 *어떻게 수정해야 할까요? 지금으로서는 RandomLottoGenerator 때문에 생성된 로또의 내용까지는 테스트하기가 어렵겠*군요.
|
|
89
|
+
> — @hyemdooly on `src/main/kotlin/lotto/domain/LottoShop.kt`
|
|
90
|
+
|
|
91
|
+
> 테스트 코드는 일종의 문서이기도 하니, *한 눈에 볼 수 있도록 하드코딩하는 것을 더 선호*하게 되었습니다.
|
|
92
|
+
> — @hyemdooly on `src/test/kotlin/lotto/domain/LottoShopTest.kt`
|
|
93
|
+
|
|
94
|
+
> 이런 식으로 *Controller에서 Generator한테 뷰의 로직을 넘겨줄 수* 있습니다. > 그럼 이건 Domain 입장에서 View를 알고 있는 것은 아닌가요? 이 의문에 대해서는 *크루들과 함께 토론*해 보시면 좋을 것 같아요!
|
|
95
|
+
> — @hyemdooly on `src/main/kotlin/lotto/domain/LottoMachine.kt`
|
|
96
|
+
|
|
97
|
+
> 지오의 의견을 읽어보니 이해가 되네요!
|
|
98
|
+
> — @hyemdooly on `src/main/kotlin/lotto/domain/LottoShop.kt`
|
|
99
|
+
|
|
100
|
+
## 얻은 교훈
|
|
101
|
+
|
|
102
|
+
- **Controller *직접 생성 X*** — DI (생성자/세터/인터페이스). *생성 책임 외부*.
|
|
103
|
+
- **테스트 *fake = 테스트 코드*에** — *프로덕션 오염* 회피.
|
|
104
|
+
- **테스트 어려움 = *책임 분리 신호*** — *RandomGenerator 의존*이 *LottoShop 테스트*를 막으면 *책임 위치 의심*.
|
|
105
|
+
- **테스트 *expect 하드코딩 = 문서*** — *동어 반복 회피* + *명세 가시성*.
|
|
106
|
+
- **변수명 *대조*** — `winLotto` vs `boughtLottos`. *대구 (對句)*가 가독성.
|
|
107
|
+
- **논리적 오류 vs null 반환** — *논리 오류 = 예외*, *형식 오류 = null*. *PR #148 (etama123) 4단계 정리*와 같은 결.
|
|
108
|
+
- **`Shop` *살 때 받기*** — *손님 정보를 처음부터 보유*보다 *주문 시 받기*가 자연 흐름.
|
|
109
|
+
- **에러 메시지 *sealed class*** — *InputView*에서 *상태별 매핑*.
|
|
110
|
+
- **`fun interface` *SAM 학습*** — *함수 하나만*인 interface는 *fun interface*로.
|
|
111
|
+
- **`LottoGenerator { view.readManualLotto() }` *람다 위임*** — *함수형 인터페이스*가 *View 책임*을 *Domain에 위임*. *추상화 vs 의존 방향* 토론 거리.
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# PR #67 — [로또] 해음 1단계 미션
|
|
2
|
+
|
|
3
|
+
- **Reviewee:** [@haeum808](https://github.com/haeum808)
|
|
4
|
+
- **PR:** https://github.com/woowacourse/kotlin-lotto/pull/67
|
|
5
|
+
- **단계:** 1단계
|
|
6
|
+
- **리뷰어:** @malibinYun
|
|
7
|
+
- **라인 코멘트:** 49
|
|
8
|
+
|
|
9
|
+
## 못한 점 + 핵심 지적
|
|
10
|
+
|
|
11
|
+
### 1. Lotto가 값 + 검증만 (행위 없음)
|
|
12
|
+
|
|
13
|
+
```kotlin
|
|
14
|
+
class Lotto(val numbers: List<LottoNumber>) {
|
|
15
|
+
init { require(numbers.size == 6) }
|
|
16
|
+
}
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
> 로또 객체가 값을 가지고, 검증하는 것 이외에 별다른 역할을 맡고 있지 않고있네요. 이 객체가 할 수 있는 일들을 다른 곳으로부터 가져와 모아두는 건 어떨까요?
|
|
20
|
+
|
|
21
|
+
→ Lotto가 *외부에 의해* 비교/매칭되는 *수동적 객체*. `lotto.match(winningLotto)` 같은 행위 부여.
|
|
22
|
+
|
|
23
|
+
### 2. LottoNumber 매번 생성 — flyweight 미적용
|
|
24
|
+
|
|
25
|
+
→ 캐시 후 재활용.
|
|
26
|
+
|
|
27
|
+
### 3. 에러 메시지에 입력값 미포함
|
|
28
|
+
|
|
29
|
+
```kotlin
|
|
30
|
+
require(value > 0) { "잘못된 금액입니다" }
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
> 어떤 값이 들어와서 Exception이 발생했는지 메시지를 담아주는 건 어떨까요?
|
|
34
|
+
|
|
35
|
+
### 4. Rank 매칭 — 모든 값 순회
|
|
36
|
+
|
|
37
|
+
```kotlin
|
|
38
|
+
fun findRank(count: Int, bonus: Boolean): Rank {
|
|
39
|
+
return values().first { it.count == count && it.bonus == bonus }
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
> 모든 값을 순회할 필요가 있을까요? 특정 경우에만 조건문을 처리하고, 나머지를 처리하게 구성해보는 건 어떨까요?
|
|
44
|
+
|
|
45
|
+
→ when으로 *특수 케이스* (5개 + 보너스 = SECOND) 분기.
|
|
46
|
+
|
|
47
|
+
## 얻은 교훈
|
|
48
|
+
|
|
49
|
+
- **값 객체에 행위 부여 필수** — 값만 있으면 *수동적 객체*.
|
|
50
|
+
- **flyweight 패턴** = 고정 범위 값 객체 재활용.
|
|
51
|
+
- **에러 메시지에 *입력값*** 포함 → 운영 디버깅 비용 ↓.
|
|
52
|
+
- **when 분기 vs 전체 순회** — 특수 케이스가 적으면 when이 명시적.
|