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,67 @@
|
|
|
1
|
+
# PR #105 — [로또 1단계] 뭉치 미션
|
|
2
|
+
|
|
3
|
+
- **Reviewee:** [@m6z1](https://github.com/m6z1)
|
|
4
|
+
- **PR:** https://github.com/woowacourse/kotlin-lotto/pull/105
|
|
5
|
+
- **단계:** 1단계
|
|
6
|
+
- **리뷰어:** @malibinYun
|
|
7
|
+
- **라인 코멘트:** 46
|
|
8
|
+
|
|
9
|
+
## 못한 점 + 핵심 지적
|
|
10
|
+
|
|
11
|
+
### 1. Lotto에 Set 미적용 (List + 중복 검증)
|
|
12
|
+
|
|
13
|
+
```kotlin
|
|
14
|
+
class Lotto(val numbers: List<LottoNumber>) {
|
|
15
|
+
init { require(numbers.toSet().size == numbers.size) } // ⚠ 매번 변환
|
|
16
|
+
}
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
> set을 활용해보는 건 어떨까요?
|
|
20
|
+
|
|
21
|
+
→ 도메인 자체에 *중복 없음 invariant*가 있다면 Set으로 저장.
|
|
22
|
+
|
|
23
|
+
### 2. LottoMachine — 테스트 어려운 구조
|
|
24
|
+
|
|
25
|
+
```kotlin
|
|
26
|
+
class LottoMachine {
|
|
27
|
+
fun generate(count: Int): List<Lotto> {
|
|
28
|
+
repeat(count) {. Random.nextInt(.). } // ⚠ Random 직접
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
> 이 클래스는 테스트하기 매우 어려운 구조네요. 랜덤 요소를 분리해내서 테스트할 수 있도록 구성해보는 건 어떨까요?
|
|
34
|
+
|
|
35
|
+
### 3. `mutableListOf + add` 패턴
|
|
36
|
+
|
|
37
|
+
```kotlin
|
|
38
|
+
val lottos = mutableListOf<Lotto>()
|
|
39
|
+
repeat(count) { lottos.add(generateOne()) }
|
|
40
|
+
return lottos
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
> 코틀린 Collections 확장함수들을 활용한다면 지금처럼 mutableList를 만들어서 add 하는 형태의 코드를 작성하지 않아도 된답니다!
|
|
44
|
+
|
|
45
|
+
→ `List(count) { generateOne() }`.
|
|
46
|
+
|
|
47
|
+
### 4. `LottoNumber` 직접 equals/hashCode
|
|
48
|
+
|
|
49
|
+
```kotlin
|
|
50
|
+
class LottoNumber(val value: Int) {
|
|
51
|
+
override fun equals(.): Boolean =.
|
|
52
|
+
override fun hashCode(): Int =.
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
> 직접 equals & hashCode를 구현하신 이유는 무엇인가요? data class 와 class의 차이점에 대해 알아보세요!
|
|
57
|
+
|
|
58
|
+
→ data class 또는 value class가 자동 생성.
|
|
59
|
+
|
|
60
|
+
### 5. LottoNumber 캐싱 미적용
|
|
61
|
+
|
|
62
|
+
## 얻은 교훈
|
|
63
|
+
|
|
64
|
+
- **도메인 invariant 표현 = 자료구조 선택**. *중복 없음*은 Set으로.
|
|
65
|
+
- **`List(count) {. }` Kotlin builder** — mutableListOf + repeat 패턴 대체.
|
|
66
|
+
- **data class / value class > 직접 equals/hashCode**.
|
|
67
|
+
- **flyweight** — 1억 티켓도 LottoNumber 45개 재활용.
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# PR #151 — [로또 2단계] 뭉치 미션
|
|
2
|
+
|
|
3
|
+
- **Reviewee:** [@m6z1](https://github.com/m6z1)
|
|
4
|
+
- **PR:** https://github.com/woowacourse/kotlin-lotto/pull/151
|
|
5
|
+
- **단계:** 2단계 (수동 로또 추가)
|
|
6
|
+
- **리뷰어:** @malibinYun
|
|
7
|
+
- **라인 코멘트:** 22
|
|
8
|
+
|
|
9
|
+
## 잘한 점 (설계 관점)
|
|
10
|
+
|
|
11
|
+
- **1단계 코멘트를 PR에 명시적 링크 + 답변** — 학습 흐름이 PR에 *명시적으로 남음*.
|
|
12
|
+
- **`LottoNumbersGenerator` 인터페이스 + `Auto*`/`Manual*` 구현체** — Strategy.
|
|
13
|
+
- **`runCatching + getOrElse`로 재시도 흐름**.
|
|
14
|
+
- **`size` 필드 vs `get()` 트레이드오프 인지** — *불변 객체*는 필드, 가변은 get().
|
|
15
|
+
- **자가 의문 PR에 풍부히 명시** — *수동 generator의 존재 의미*, *LottoMachine 호출 = Lotto 호출과 무엇이 다른가* 등.
|
|
16
|
+
|
|
17
|
+
## 못한 점 (설계 관점)
|
|
18
|
+
|
|
19
|
+
### 1. `LottoMachine`이 *하는 일 부재*
|
|
20
|
+
|
|
21
|
+
```kotlin
|
|
22
|
+
class LottoMachine {. }
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
리뷰어: "이 객체는 하는 일이 전혀 없어요. LottoMachine.createLotto()를 호출하는 것과 Lotto() 생성자를 호출하는 것은 무엇이 다른가요? Controller에 있는 *로또 생성에 대한 일련의 로직*을 분리해 보세요." + "이 객체가 LottoNumbersGenerator를 가지도록 만들어 보세요. 테스트 가능하도록 구조를 변경하면서요." 학생 수정: "로또 번호 생성기를 추상화하여, 자동 생성기와 수동 생성기를 구현. 로또 기계에서 로또를 발행할 때는 로또 번호 생성기와 발행할 로또의 개수를 매개변수로 받아 로또 생성 로직을 `LottoMachine` 객체로 분리."
|
|
26
|
+
|
|
27
|
+
### 2. `WinningLotto.findLottoRank`을 `Lotto.getRank(winningLotto)`로 이동
|
|
28
|
+
|
|
29
|
+
```kotlin
|
|
30
|
+
// 변경
|
|
31
|
+
fun getRank(winningLotto: WinningLotto): Rank {
|
|
32
|
+
val matchCount = getMatchCount(winningLotto.winningNumbers)
|
|
33
|
+
val isMatchedBonus = isMatchedBonusNumber(winningLotto.bonusNumber)
|
|
34
|
+
return Rank.findRank(matchCount, isMatchedBonus)
|
|
35
|
+
}
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
리뷰어: "이 메서드의 위치는 어떤 이유로 옮겨진 걸까요?" 학생: "Lotto 내부로 옮긴 후의 로직을 보니 lotto에서 *winningLotto의 값을 직접 꺼내 사용*하게 되는 일이 생겼습니다. WinningLotto에게 직접 메시지(몇 개 맞는지/보너스 포함 여부)를 던지게 되어도 Lotto 내부의 메서드와 같은 로직 → 다시 *WinningLotto가 Lotto를 받아* '내 기준 너는 몇 등이다'로 반환." — *메시지 방향*을 다시 뒤집음.
|
|
39
|
+
|
|
40
|
+
### 3. `LottoCount.validateLottoMaxCount(other)` — 자기 자신 타입을 받는 검증
|
|
41
|
+
|
|
42
|
+
```kotlin
|
|
43
|
+
class LottoCount(val count: Int) {
|
|
44
|
+
fun validateLottoMaxCount(totalCount: LottoCount) {
|
|
45
|
+
require(count <= totalCount.count) {. }
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
리뷰어: "이 메서드는 어떤 역할을 수행하는 건지 알기가 너무 어렵네요. *왜 이 객체 안에 존재*해야 하는 것인지, *이름으로 어떤 일*을 하는 것인지, *왜 자기 자신과 같은 인스턴스*를 받아야 하는지 등등에서요. 정말 필요한 기능이었나요? 또, Exception을 던져서만 로직을 구성할 수 있는 것이었나요?" 학생: "오류가 생기면 무조건 Exception을 던진다고만 생각해서 구현. *isAvailablePurchase* 함수를 구현하여, 구매가 불가능할 경우 사용자에게 다시 입력받도록 수정."
|
|
51
|
+
|
|
52
|
+
### 4. `data class Lotto`로 변경 — 그러나 변경 의도
|
|
53
|
+
|
|
54
|
+
```kotlin
|
|
55
|
+
- class Lotto(
|
|
56
|
+
+ data class Lotto(
|
|
57
|
+
val numbers: List<LottoNumber>,
|
|
58
|
+
)
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
학생: "사용자가 중복된 값을 입력했을 때 *입력한 로또 번호 개수는 5개입니다*라는 메시지를 보고 중복된 값이 제거되어 입력한 로또 번호 개수가 5개라는 것을 사용자가 판단하기엔 *불친절*하다고 생각." 리뷰어: "여전히 *도메인을 개발하는 사람과 어플리케이션을 사용하는 사람*과의 관계가 공감이 가지 않네요. 뷰에서 중복된 값 자체를 받지 못하도록 막는 기능이 생긴다면 여기의 기능은 의미가 있을까요? *Exception 메시지가 정말 애플리케이션 사용자에게 노출되는 메시지인가요?*" — 도메인 검증 메시지는 *개발자용*. 학생 깨달음: "이전에 언급해주셨던 *Glide.with()의 여러 옵션* 라는 말씀과 연결 → 가변인자와 List를 통해 *여러 옵션*을 두도록."
|
|
62
|
+
|
|
63
|
+
### 5. `isMatchedBonusNumber` — 너무 좁은 이름
|
|
64
|
+
|
|
65
|
+
리뷰어: "이 메서드의 내용은 꼭 *보너스 번호를 포함*하는지 여부만을 알려주는 기능일까요?" 학생: "함수의 네이밍 및 매개변수의 네이밍을 number로 수정. 보너스 번호가 아닌 *다른 번호로도 포함*되어 있는지 재사용할 수 있도록 수정." — `containsNumber(LottoNumber)`로 일반화.
|
|
66
|
+
|
|
67
|
+
### 6. `Lotto`가 `List`인가 `Set`인가
|
|
68
|
+
|
|
69
|
+
리뷰어: "오 그럼에도 불구하고 *주 생성자는 여전히 Set이 아닌 List*로 둔 이유가 있으신가요?" — 학생이 List 유지 의도 미명시.
|
|
70
|
+
|
|
71
|
+
### 7. *Generator 호출 vs Lotto 호출* 자가 의문
|
|
72
|
+
|
|
73
|
+
학생: "`Lotto(numbers)`를 이용해 검증을 진행. 이 과정에서 *불필요한 Lotto 인스턴스가 여러 번 생성*. 입력할 때마다 `LottoMachine.createLotto(lottoNumbers)`를 호출하여 로또 하나씩 생성해야 할까? 하지만, 위 로직으로 구현하게 되면 결국 *LottoMachine이 필요할까*?" 리뷰어: "지금의 고민이 굉장히 유의미한 고민이라 생각해요. *어디든 장단점과 트레이드 오프*가 생길 수밖에 없다는 점을 이 고민으로 완전히 체험. 저는 로또 머신이라는 객체가 존재함으로써 *로또를 만들 때는 항상 로또의 생성자를 직접 불러야 하나? 아니면 다른 객체가 있나? 라는 고민을 아예 배제*시켜 줄 수 있다 생각해요."
|
|
74
|
+
|
|
75
|
+
### 8. `LottoMachine` 생성자 vs 파라미터 — 학습 시드
|
|
76
|
+
|
|
77
|
+
리뷰어: "파라미터로 구성한 것도 하나의 방법이지만, 생성자로도 변경해 보시면 좋겠어요! *어떤 차이점이 있을지, 장단점은 무엇일지* 고민해 보시면서요."
|
|
78
|
+
|
|
79
|
+
## 리뷰어 의견 요지
|
|
80
|
+
|
|
81
|
+
- **도메인 검증 메시지는 *개발자용***, 사용자 메시지는 View 책임.
|
|
82
|
+
- **객체에 *메시지 던지기*로 책임 위임** — `lotto.containsNumber(bonus)` 같이 일반화된 메시지.
|
|
83
|
+
- **자기 자신 타입을 받는 검증 메서드** = *이름과 책임 모호 신호*.
|
|
84
|
+
- **`Lotto`/`LottoMachine` 둘 다 *생성 책임 위치*** — 머신이 있으면 *고민 배제*, 없으면 *추가 객체 없음*. trade-off.
|
|
85
|
+
- **`LottoMachine`은 *LottoNumbersGenerator 보유*가 자연** — *생성자 주입*으로 *상태 + 행위*.
|
|
86
|
+
|
|
87
|
+
- **대표 인용:**
|
|
88
|
+
> 이 객체는 하는 일이 전혀 없어요. LottoMachine.createLotto()를 호출하는 것과 Lotto() 생성자를 호출하는 것은 무엇이 다른가요?
|
|
89
|
+
> — @malibinYun on `src/main/kotlin/lotto/model/LottoMachine.kt`
|
|
90
|
+
|
|
91
|
+
> Exception 메시지가 정말 애플리케이션 사용자에게 노출되는 메시지인가요?
|
|
92
|
+
> — @malibinYun on `src/main/kotlin/lotto/model/Lotto.kt`
|
|
93
|
+
|
|
94
|
+
> 이 메서드의 내용은 꼭 "보너스 번호를 포함"하는지 여부만을 알려주는 기능일까요?
|
|
95
|
+
> — @malibinYun on `src/main/kotlin/lotto/model/Lotto.kt`
|
|
96
|
+
|
|
97
|
+
## 얻은 교훈
|
|
98
|
+
|
|
99
|
+
- **검증 메시지 = *개발자용***, 사용자 메시지는 View 책임. 둘을 혼동하면 *도메인이 사용자를 의식*.
|
|
100
|
+
- **`isXxxBonusNumber` 같은 *좁은 이름*은 *기능 일반화 신호*** — `containsNumber(LottoNumber)`가 *재사용 가능*.
|
|
101
|
+
- **자기 자신 타입을 받는 검증** — *왜 객체 안에 있나*, *이름이 의도를 표현하나* 의심.
|
|
102
|
+
- **Generator vs 직접 생성자 = 트레이드오프** — Generator는 *고민 배제*, 직접은 *추가 객체 없음*. *어떤 환경*에 따라 선택.
|
|
103
|
+
- **`LottoMachine`은 *LottoNumbersGenerator 보유*가 자연** — 생성자 주입으로 *변경 단일점*.
|
|
104
|
+
- **PR에 *이전 라운드 코멘트 링크*** — 학습 흐름 가시화 + 리뷰어 추적 용이.
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
# PR #127 — [로또 1단계] 메다 미션
|
|
2
|
+
|
|
3
|
+
- **Reviewee:** [@medAndro](https://github.com/medAndro)
|
|
4
|
+
- **PR:** https://github.com/woowacourse/kotlin-lotto/pull/127
|
|
5
|
+
- **단계:** 1단계
|
|
6
|
+
- **리뷰어:** @lee-ji-hoon
|
|
7
|
+
- **라인 코멘트:** 36
|
|
8
|
+
|
|
9
|
+
## 잘한 점 (설계 관점)
|
|
10
|
+
|
|
11
|
+
- **원시값 포장(`LottoNumber`/`PurchaseAmount`/`PurchaseQuantity`/`EarningRate`)을 광범위하게 적용** — 각 도메인 어휘 분리.
|
|
12
|
+
- **`LottoGenerator` 분리** — Lotto 생성 로직과 Lotto 검증 분리.
|
|
13
|
+
- **`enum class Rank`로 등수+상금** — 한 enum이 등수 분류 + 상금 가짐.
|
|
14
|
+
- **`PurchaseAmount` 검증을 `PurchaseQuantity`보다 먼저** — 일급 객체끼리 책임 위임 시도.
|
|
15
|
+
- **`Rank.entries.associateWith { 0 }`로 초기 Map 형성** — 누락 등수도 0으로 시작.
|
|
16
|
+
|
|
17
|
+
## 못한 점 (설계 관점)
|
|
18
|
+
|
|
19
|
+
### 1. `Lotto`가 `List<LottoNumber>` — 중복 검증 수동
|
|
20
|
+
|
|
21
|
+
```kotlin
|
|
22
|
+
class Lotto(val lottoNumbers: List<LottoNumber>) {
|
|
23
|
+
init {
|
|
24
|
+
require(lottoNumbers.size == 6) {. }
|
|
25
|
+
require(lottoNumbers.map { it.number }.distinct().size == 6) {
|
|
26
|
+
HAS_DUPLICATE_NUMBERS.format(
|
|
27
|
+
lottoNumbers.map { it.number }.groupBy { it }
|
|
28
|
+
.filter { it.value.size > 1 }.keys.toList().joinToString(", ")
|
|
29
|
+
)
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
리뷰어: "특정 자료구조를 사용하면 외부에 중복이 불가능한 것을 알려주기도 하면서 중복에 대한 것을 자연스럽게 방지할 수가 있는데요. 그렇게 되면 init에 체이닝도 조금 줄어들 수 있겠네요." — `Set<LottoNumber>` 시그니처면 *중복 불가가 타입에 표현*. init 체이닝 6단계가 줄어듦.
|
|
36
|
+
|
|
37
|
+
### 2. 한 `init`에 두 책임 + 7단계 체이닝
|
|
38
|
+
|
|
39
|
+
리뷰어: "지금 한 곳에 서로 다른 역할을 하는 체이닝이 있기 때문인데요. 이 체이닝이 각각 무슨 역할을 하는지를 직접 하나하나 분석을 해서 보는 것 보다 함수로 분리를 한다면 어떨까요?" — *"한 줄에 점 하나"* 원칙. 의도가 다른 체이닝은 메서드명으로 분리.
|
|
40
|
+
|
|
41
|
+
### 3. `LottoConstants` — 비즈니스 정책과 도메인 규칙 혼재
|
|
42
|
+
|
|
43
|
+
```kotlin
|
|
44
|
+
object LottoConstants {
|
|
45
|
+
const val LOTTO_PRICE = 1000 // 비즈니스 정책 (변동)
|
|
46
|
+
const val NUMBER_OF_LOTTO_NUMBERS = 6 // 도메인 규칙 (불변)
|
|
47
|
+
private const val MINIMUM_LOTTO_NUMBER = 1
|
|
48
|
+
private const val MAXIMUM_LOTTO_NUMBER = 45
|
|
49
|
+
val LOTTO_RANGE = MINIMUM_LOTTO_NUMBER..MAXIMUM_LOTTO_NUMBER
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
리뷰어: "로또의 가격은 1000원이라는 내용은 비즈니스적인 내용으로 생각할 수도 있지 않을까요?" — 학생 인정: "가격 인상 등 서비스 운영 과정에서 유동적으로 변경되는 *비즈니스 정책*과 운영 중 변경을 할 일이 거의 없는 *도메인 규칙*을 실수로 혼재해 버린 것 같습니다." → 변경 빈도가 다른 상수는 같은 객체에 두지 말 것.
|
|
54
|
+
|
|
55
|
+
### 4. `LottoNumber`가 인스턴스 폭증 위험
|
|
56
|
+
|
|
57
|
+
```kotlin
|
|
58
|
+
class LottoNumber(val number: Int) {. }
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
리뷰어: "`LottoNumber`를 사용하는 `Lotto`가 수십만 개 생겼다고 했을 때 `LottoNumber`도 수십만 개가 생길 텐데요. 이런 상황에서 원시값을 래핑한 경우 특정 클래스를 사용한다면 조금 더 최적화가 가능한데요 한 번 찾아보면 어떨까요?" — *Flyweight* (`(1..45)` 사전 캐싱) 또는 `value class`.
|
|
62
|
+
|
|
63
|
+
### 5. `PurchaseAmount`의 클래스명 vs 책임 불일치
|
|
64
|
+
|
|
65
|
+
```kotlin
|
|
66
|
+
class PurchaseAmount(val amount: Int) {
|
|
67
|
+
init {
|
|
68
|
+
require(amount > 0)
|
|
69
|
+
require(amount % LOTTO_PRICE == 0) // 로또 가격을 이미 안다
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
리뷰어: "`구매가격`만으로 보이지만 init을 보면 이 클래스는 로또라는 도메인에 많이 의존되어 있는 것 같은데요. 1) 로또에 대한 의존을 줄인다. 2) 로또에 대한 의존을 두고 클래스명을 수정한다. 어떤 것이 적합할지 한 번 고민해보시면 좋을거 같습니다." — 학생 수긍: "*로또구매가격*인 값을 포장하는 클래스는 필요하다고 생각되어 클래스 이름만 변경." → `LottoPayInfo`로 변경.
|
|
75
|
+
|
|
76
|
+
### 6. `PurchaseQuantity`가 `runCatching`으로 자기 책임 중복 검증
|
|
77
|
+
|
|
78
|
+
```kotlin
|
|
79
|
+
class PurchaseQuantity(purchaseAmount: PurchaseAmount) {
|
|
80
|
+
val quantity = runCatching { purchaseAmount.amount / LOTTO_PRICE }.getOrElse {
|
|
81
|
+
throw IllegalArgumentException(INDIVISIBLE_VALUE_ERROR.format(purchaseAmount.amount))
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
리뷰어: "이 도메인 모델에 대한 테스트 커밋이 안 보이네요. 이 runCatching이 정말 필요했던 것인지 한 번 테스트 코드를 구현해 보면 좋을 것 같습니다." 학생 자가 발견: "`PurchaseAmount`에서 이미 확인했던 걸 또 확인하고 있었네요." → 일급 객체로 받았으면 다시 검증할 필요 없음.
|
|
87
|
+
|
|
88
|
+
### 7. `InputView`가 직접 `Lotto`/`WinningLotto`/`PurchaseAmount` 생성
|
|
89
|
+
|
|
90
|
+
```kotlin
|
|
91
|
+
class InputView {
|
|
92
|
+
fun readPurchaseAmount(): PurchaseAmount {. }
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
리뷰어: "View가 직접 Model을 만들어 줘도 상관이 없을까요? View의 역할은 무엇일까요?" 학생 정리: "뷰: 단순 형식 변환(String → Int) + 도메인 객체를 전달받아 출력. 컨트롤러: 도메인 객체 생성 + 흐름 관리 + 예외 *처리*. 도메인: 비즈니스 로직 구현 + 자기 검증 및 예외 *발생*."
|
|
97
|
+
|
|
98
|
+
### 8. `LottoCalculator.getWinningStats()` — Mutable Map 누적
|
|
99
|
+
|
|
100
|
+
```kotlin
|
|
101
|
+
private fun getWinningStats(): Map<Rank, Int> {
|
|
102
|
+
val winningStats: MutableMap<Rank, Int> = Rank.entries.associateWith { 0 }.toMutableMap()
|
|
103
|
+
lottos.forEach {
|
|
104
|
+
val rank = winningLotto.getRank(it)
|
|
105
|
+
winningStats[rank] = (winningStats[rank]?.plus(1)) ?: 1
|
|
106
|
+
}
|
|
107
|
+
return winningStats
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
리뷰어: "Mutable한 Map이 없이 이 함수가 하는 동작을 충분히 수정이 가능한데요. `groupingBy` + `eachCount` 등을 잘 사용해보시면 좋을 거 같습니다." — `lottos.groupingBy { winningLotto.getRank(it) }.eachCount()` 한 줄.
|
|
112
|
+
|
|
113
|
+
### 9. `LottoGenerator`를 별도 클래스로
|
|
114
|
+
|
|
115
|
+
```kotlin
|
|
116
|
+
class LottoGenerator {
|
|
117
|
+
fun generateLotto(): Lotto {. }
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
리뷰어: "Lotto의 생성자나 invoke에서 처리할 수 있을 거 같은데 `LottoGenerator`로 분리를 했을 때 Lotto가 해야 할 일을 나눈 것이 되는데 이렇게 됐을 때 어떤 이점이 있다고 생각하시나요?" 후속: "누군가 `Lotto` Class만 봤을 때 `LottoGenerator`의 유무를 알 수 있을까요? 그냥 `Lotto` 클래스를 그냥 넣어서 만들어 버릴 수도 있을 거 같아요. 그런 상황에서는 `Lotto` 내부에 본인이 생성을 전담하는 방법도 있는데요!" — `Lotto.private constructor + companion object` 팩토리.
|
|
122
|
+
|
|
123
|
+
### 10. 테스트명/검증 대상 불일치
|
|
124
|
+
|
|
125
|
+
```kotlin
|
|
126
|
+
@Test
|
|
127
|
+
fun `6개의 로또 번호를 생성한다`() {
|
|
128
|
+
assertDoesNotThrow { LottoGenerator().generateLotto() }
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
@ValueSource(doubles = [0.051, 0.052, 0.053, 0.054])
|
|
132
|
+
fun `소수점 아래 2자리로 반올림한다`(rate: Double) {
|
|
133
|
+
val earningRate = EarningRate(rate)
|
|
134
|
+
assertThat(earningRate.rate).isEqualTo(0.05)
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
리뷰어: "이 테스트 코드는 함수명에 맞는 테스트 코드를 만들고 수행 중인 게 맞을까요?" + "소수점 아래 2자리로 반올림한다. 이것은 어떠한 것을 확인하기 위한 테스트인가요?" + "테스트 코드 함수명을 짤 때 `given` `when` `then` 형식으로 구현을 해 보면서…" — 테스트명은 *의도*, 본문은 *검증 대상*과 일치해야.
|
|
139
|
+
|
|
140
|
+
### 11. `OutputView`가 손익 분기 직접 판단
|
|
141
|
+
|
|
142
|
+
```kotlin
|
|
143
|
+
fun printLottoEarningRate(earningRate: EarningRate) {
|
|
144
|
+
val gainLossText = if (earningRate.rate > 1) "이득이라는"
|
|
145
|
+
else (if (earningRate.rate == 1.0) "본전이라는" else "손해라는")
|
|
146
|
+
println("총 수익률은 ${earningRate.rate}입니다.. $gainLossText.")
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
리뷰어: "View의 관점에서는 지금 1보다 큰지 작은지 같은지를 비교하기 보다는 rate에 따른 `상태`를 만들고 그 상태에 따라 Text가 변경이 되는 건 어떨까요?" — *손익 상태*는 도메인이 판별, View는 상태→텍스트만.
|
|
151
|
+
|
|
152
|
+
## 리뷰어 의견 요지
|
|
153
|
+
|
|
154
|
+
1. **자료구조가 invariant를 표현** — `Set<LottoNumber>`이면 중복 불가가 *타입에 새겨짐*.
|
|
155
|
+
2. **비즈니스 정책 vs 도메인 규칙** — 변경 빈도가 다른 상수는 같은 객체에 두면 안 됨. 가격은 정책, 6개·1~45는 규칙.
|
|
156
|
+
3. **검증을 *일급 객체 통과*로 압축** — 한 번 검증된 객체는 다시 검증하지 않음.
|
|
157
|
+
4. **View는 *형식 변환 + 출력*만** — 도메인 객체 생성은 Controller.
|
|
158
|
+
5. **함수형 어휘로 누적 패턴 압축** — `groupingBy {. }.eachCount()`.
|
|
159
|
+
6. **Generator의 필요성 = *Lotto 외부에서 생성 정책을 갖는가*** — 그렇지 않으면 `Lotto.companion`이 충분.
|
|
160
|
+
7. **테스트명/본문/검증 대상 일치** — given-when-then으로 명시.
|
|
161
|
+
8. **View 분기는 *상태*로 표현** — 1보다 큰지 작은지 같은지는 *비즈니스 판정*.
|
|
162
|
+
|
|
163
|
+
- **대표 인용:**
|
|
164
|
+
> 로또의 가격은 1000원이라는 내용은 비즈니스적인 내용으로 생각할 수도 있지 않을까요?
|
|
165
|
+
> — @lee-ji-hoon on `src/main/kotlin/lotto/constants/LottoConstants.kt`
|
|
166
|
+
|
|
167
|
+
> `LottoNumber`를 사용하는 `Lotto`가 수십만 개 생겼다고 했을 때 `LottoNumber`도 수십만 개가 생길 텐데요. … 한 번 찾아보면 어떨까요?
|
|
168
|
+
> — @lee-ji-hoon on `src/main/kotlin/lotto/domain/value/LottoNumber.kt`
|
|
169
|
+
|
|
170
|
+
> 누군가 `Lotto` Class만 봤을 때 `LottoGenerator`의 유무를 알 수 있을까요? 그냥 `Lotto` 클래스를 그냥 넣어서 만들어 버릴 수도 있을 거 같아요.
|
|
171
|
+
> — @lee-ji-hoon on `src/main/kotlin/lotto/domain/service/LottoGenerator.kt`
|
|
172
|
+
|
|
173
|
+
> View의 관점에서는 지금 1보다 큰지 작은지 같은지를 비교하기 보다는 rate에 따른 `상태`를 만들고 그 상태에 따라 Text가 변경이 되는 건 어떨까요?
|
|
174
|
+
> — @lee-ji-hoon on `src/main/kotlin/lotto/view/OutputView.kt`
|
|
175
|
+
|
|
176
|
+
## 얻은 교훈
|
|
177
|
+
|
|
178
|
+
- **자료구조 선택 = invariant 표현**. `List<LottoNumber>`에서 중복 검증을 직접 하지 말고 `Set<LottoNumber>`이면 타입이 보장.
|
|
179
|
+
- **상수의 *변경 빈도*가 다르면 같은 객체에 두지 말 것**. 정책(가격)과 규칙(개수·범위)을 분리하면 변경 영향 범위가 명확.
|
|
180
|
+
- **일급 객체를 *받았다는 것* = 검증 완료**. 받은 쪽에서 다시 검증하면 일급 객체 도입 의미 소실.
|
|
181
|
+
- **View는 *형식 변환 + 출력*만, 도메인 생성은 Controller**. View가 도메인을 만들면 *모델/뷰 책임 경계*가 모호.
|
|
182
|
+
- **누적 패턴은 함수형 어휘로 압축 가능**. `MutableMap + forEach + ?:plus(1)`은 `groupingBy{}.eachCount()`로.
|
|
183
|
+
- **Generator 분리의 *이점*은 *Lotto 외부에서 생성 전략이 필요할 때***. 단일 전략이면 `Lotto.companion`이 응집도 더 높음.
|
|
184
|
+
- **테스트명 = 의도, 본문 = 그 의도의 직접 검증**. 함수명 `소수점 아래 2자리로 반올림한다`는 *주어가 누락*. `수익률은 소수점 3번째 자리에서 반올림된다`로.
|
|
185
|
+
- **View 분기는 *상태*로 표현 가능할 때 그렇게 하라**. `if (rate > 1)`은 *비즈니스 판정*; `enum class ProfitState`로 도메인이 결정, View는 매핑만.
|
|
186
|
+
- **객체 지향 생활 체조 원칙 *한 줄에 점 하나*** — 여러 의도가 한 체이닝에 섞이면 메서드명 부여로 의도 표현.
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# PR #130 — [로또 2단계] 메다 미션
|
|
2
|
+
|
|
3
|
+
- **Reviewee:** [@medAndro](https://github.com/medAndro)
|
|
4
|
+
- **PR:** https://github.com/woowacourse/kotlin-lotto/pull/130
|
|
5
|
+
- **단계:** 2단계
|
|
6
|
+
- **리뷰어:** @lee-ji-hoon
|
|
7
|
+
- **라인 코멘트:** 66
|
|
8
|
+
|
|
9
|
+
## 잘한 점 (설계 관점)
|
|
10
|
+
|
|
11
|
+
- **`GainLoss`, `Rank` enum 분리** — 이득/손실 구분.
|
|
12
|
+
- **`EarningInfo` 도메인** — 수익 정보 분리.
|
|
13
|
+
- **`RandomLottoNumbersGenerator`** — 인터페이스 분리.
|
|
14
|
+
|
|
15
|
+
## 못한 점 (설계 관점)
|
|
16
|
+
|
|
17
|
+
### 1. enum의 `enums/` god-folder
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
lotto/
|
|
21
|
+
enums/
|
|
22
|
+
GainLoss.kt
|
|
23
|
+
Rank.kt
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
> 이번엔 패키지도 신경을 써볼까요? `enums` 안에 `GainLoss` `Rank` 두 가지가 존재하는데 enums라는 패키지 하나로 관리를 한다면 이 패키지는 Constants object 처럼 무진장 많아 질거 같아요. 그래서 제가 추천하는 방법은 이 enum의 역할에 대해서 신경을 써서 패키징을 해보면 좋을거 같아요. 만약 이 enum이 domain 영역이라면 도메인 패키지로.
|
|
27
|
+
|
|
28
|
+
→ 패키지명 = *기술 분류* (enums, util) ≠ *도메인 분류* (lotto.domain).
|
|
29
|
+
|
|
30
|
+
### 2. `value/` 패키지 — 무슨 의미?
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
lotto/
|
|
34
|
+
domain/
|
|
35
|
+
value/
|
|
36
|
+
EarningInfo.kt
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
> value라는 패키지는 무엇을 의미하는 패키지일까요?
|
|
40
|
+
|
|
41
|
+
→ value object를 위한 패키지라면 *도메인 의미*가 약함. domain 평탄화 권장.
|
|
42
|
+
|
|
43
|
+
### 3. `EarningInfo` 가 UI 텍스트 보유
|
|
44
|
+
|
|
45
|
+
```kotlin
|
|
46
|
+
class EarningInfo(.) {
|
|
47
|
+
val gainLossDescription: String = when (.) {
|
|
48
|
+
Gain -> "이득"
|
|
49
|
+
Loss -> "이라는"
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
> EarningInfo는 domain model인데 "이득", "이라는" 같은 View에 표시될 Text를 알 필요가 있을까요?
|
|
55
|
+
|
|
56
|
+
→ 도메인은 *판정*만, *표현 문자열*은 OutputView.
|
|
57
|
+
|
|
58
|
+
### 4. `GainLoss` 생성 위치 — 호출자 의존
|
|
59
|
+
|
|
60
|
+
```kotlin
|
|
61
|
+
class EarningInfo(.) {
|
|
62
|
+
val gainLoss: GainLoss = GainLoss.from(rate) // ⚠ EarningInfo가 만듦
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
→ GainLoss의 역할 정의가 모호. enum이 *판정만 하는* 것인지, *표현까지 가진* 것인지 결정 필요.
|
|
67
|
+
|
|
68
|
+
### 5. 테스트에 외부 API 사용
|
|
69
|
+
|
|
70
|
+
```kotlin
|
|
71
|
+
@Test
|
|
72
|
+
fun `랜덤 로또 번호 생성`() {
|
|
73
|
+
val numbers = RandomLottoNumbersGenerator().generate()
|
|
74
|
+
assertThat(numbers.sortedBy { it.value }).isEqualTo(.)
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
> 이 테스트에서 `sortedBy` 같은 Collection API를 사용을 해야했을까요? `sortedBy` 같은 외부 API를 써야만 하는 상황을 테스트를 해야 하는 것일까?에 대해서 고민을 해보면 좋습니다.
|
|
79
|
+
|
|
80
|
+
→ sortedBy를 테스트 코드에 넣는 것은 *프로덕션 코드가 정렬하지 않음을 시사*. 정렬이 도메인 요구라면 도메인이 정렬된 상태로 반환.
|
|
81
|
+
|
|
82
|
+
### 6. 테스트 함수명에 "예외가 발생한다"
|
|
83
|
+
|
|
84
|
+
```kotlin
|
|
85
|
+
@Test fun `잘못된 입력 시 예외가 발생을 한다`() {. }
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
> 테스트 함수명에 `예외가 발생을 한다.` 라는 것을 지금 꼭 표현을 해야 할까요? 예외를 발생하지 않고 상태를 반환한다던지 하게 되면 함수명 + 내부 구현까지 전부 바뀌게 될 것입니다.
|
|
89
|
+
|
|
90
|
+
→ 함수명은 *시나리오*만, *구현 방식*(예외)은 본문에. 구현 변경 시 함수명도 안 바뀜.
|
|
91
|
+
|
|
92
|
+
### 7. 반자동 로또 확장 시 대응?
|
|
93
|
+
|
|
94
|
+
```kotlin
|
|
95
|
+
class LottoMachine {
|
|
96
|
+
fun generate(manualCount: Int): Lottos =.
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
> 나중에 만약 반자동 로또가 나오게 된다면 이 함수는 이제 반자동 로또 넘버까지 받게 될텐데요
|
|
101
|
+
|
|
102
|
+
→ 확장성 압박 시뮬레이션. 수동/자동/반자동을 *Strategy*로 표현하면 함수 시그니처 안 바뀜.
|
|
103
|
+
|
|
104
|
+
## 리뷰어 의견 요지
|
|
105
|
+
|
|
106
|
+
리뷰어 @lee-ji-hoon의 가르침:
|
|
107
|
+
|
|
108
|
+
1. **패키지명 = 도메인 분류** — `enums/`, `util/`, `value/`는 기술 분류. lotto 도메인을 표현하는 패키지로.
|
|
109
|
+
|
|
110
|
+
2. **enum 데이터의 UI 누수** — `GainLoss`에 "이득"/"이라는" 같은 표시 문자.
|
|
111
|
+
|
|
112
|
+
3. **테스트가 *프로덕션의 약점*을 드러냄** — sortedBy를 테스트에 쓴다 = 프로덕션이 정렬 안 함.
|
|
113
|
+
|
|
114
|
+
4. **테스트 함수명 = 시나리오 + 결과 (구현 무관)**.
|
|
115
|
+
|
|
116
|
+
5. **확장 시나리오 압박** — 반자동 로또 시 함수 시그니처 견디는가?
|
|
117
|
+
|
|
118
|
+
- **대표 인용:**
|
|
119
|
+
> 이번엔 패키지도 신경을 써볼까요? `enums` 안에 `GainLoss` `Rank` 두 가지가 존재하는데 enums라는 패키지 하나로 관리를 한다면 이 패키지는 Constants object 처럼 무진장 많아 질거 같아요.
|
|
120
|
+
>
|
|
121
|
+
> — @lee-ji-hoon on `src/main/kotlin/lotto/enums/GainLoss.kt`
|
|
122
|
+
|
|
123
|
+
> 이 테스트에서 `sortedBy` 같은 Collection API를 사용을 해야했을까요? `sortedBy` 같은 외부 API를 써야만 하는 상황을 테스트를 해야 하는 것일까?에 대해서 고민을 해보면 좋습니다.
|
|
124
|
+
>
|
|
125
|
+
> — @lee-ji-hoon on `src/test/kotlin/lotto/service/RandomLottoNumbersGeneratorTest.kt`
|
|
126
|
+
|
|
127
|
+
## 얻은 교훈
|
|
128
|
+
|
|
129
|
+
- **패키지명 = 도메인 어휘**. `enums/`, `util/`, `value/`는 *기술 분류*로 god-folder가 됨. 같은 enum도 *Rank*는 lotto.domain, *AnimalKind*는 zoo.domain.
|
|
130
|
+
- **테스트가 프로덕션 약점 폭로**. 테스트에서 정렬/필터/조작이 필요하면 프로덕션이 *완성된 형태*로 안 주고 있는 신호.
|
|
131
|
+
- **테스트 함수명에 구현 방식 (예외) 박지 말 것**. "잘못된 입력에 대한 처리"가 시나리오, 처리 방식 (예외 vs 빈 결과 반환)은 본문.
|
|
132
|
+
- **확장 시나리오 압박 = 인터페이스 도입 시점**. 수동/자동/반자동을 함수 인자로 받으면 추가마다 시그니처 변경. Strategy로 *변경 없이 확장*.
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# PR #110 — [로또 1단계] 다이스 미션
|
|
2
|
+
|
|
3
|
+
- **Reviewee:** [@moondev03](https://github.com/moondev03)
|
|
4
|
+
- **PR:** https://github.com/woowacourse/kotlin-lotto/pull/110
|
|
5
|
+
- **단계:** 1단계
|
|
6
|
+
- **리뷰어:** @krrong
|
|
7
|
+
- **라인 코멘트:** 50
|
|
8
|
+
|
|
9
|
+
## 잘한 점 (설계 관점)
|
|
10
|
+
|
|
11
|
+
- **`Lotto`, `LottoNumber`, `LottoNumbers`, `WinningNumbers`, `LottoRank` 분리**.
|
|
12
|
+
- **README 커밋 단위 일치** — 리뷰 편의성 ↑.
|
|
13
|
+
|
|
14
|
+
## 못한 점 (설계 관점)
|
|
15
|
+
|
|
16
|
+
### 1. 입력 형식 검증 미흡 — `1, 2, 3, 4, 5, 6` (공백) 처리
|
|
17
|
+
|
|
18
|
+
```kotlin
|
|
19
|
+
fun parseWinning(input: String): List<Int> {
|
|
20
|
+
return input.split(",").map { it.toInt() } // ⚠ 공백 미처리
|
|
21
|
+
}
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
리뷰어:
|
|
25
|
+
|
|
26
|
+
> 게임을 실행해보면서 당첨 번호를 `1, 2, 3, 4, 5, 6` 처럼 입력했더니 예외가 발생하네요. 메시지로 `숫자만 입력해주세요` 라고 나와서 어떻게 입력해야 하는가를 고민하느라 애를 먹었네요. 이러한 경우도 처리해주면 좋겠어요!
|
|
27
|
+
|
|
28
|
+
→ `.split(",").map { it.trim().toInt() }`. UX 친화.
|
|
29
|
+
|
|
30
|
+
### 2. `LottoRank`에 `matchBonus` 필드 — racingcar/lotto 반복 패턴
|
|
31
|
+
|
|
32
|
+
> 그런데 `LottoRank`가 matchBonus도 들고있어야 할까요?
|
|
33
|
+
|
|
34
|
+
→ matchBonus = *판별 입력*이지 *Rank의 영구 속성*이 아님.
|
|
35
|
+
|
|
36
|
+
### 3. `Lotto`와 `WinningNumbers` 거의 동일 (중복)
|
|
37
|
+
|
|
38
|
+
```kotlin
|
|
39
|
+
class Lotto(val numbers: LottoNumbers) {. }
|
|
40
|
+
class WinningNumbers(val numbers: LottoNumbers) {. }
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
> `WinningNumbers`와 클래스명을 제외하고 완전히 일치하네요. `Lotto`의 역할과 `WinningNumbers`의 역할은 각각 무엇인가요?
|
|
44
|
+
|
|
45
|
+
→ 둘 다 LottoNumbers wrapping이면 *역할 분리 의도가 무엇인지* 명확히. 같으면 합치거나 *조합*.
|
|
46
|
+
|
|
47
|
+
### 4. `LottoNumbers` 상속 — 검증 중복 회피 시도
|
|
48
|
+
|
|
49
|
+
학생:
|
|
50
|
+
|
|
51
|
+
> 현재 Lotto와 WinningNumbers에서 중복된 LottoNumber 검증 로직을 각각 수행하도록 구현했습니다. 이를 위해 LottoNumbers 클래스를 생성하고, 해당 클래스를 상속받아 검증이 이루어지도록 했습니다.
|
|
52
|
+
|
|
53
|
+
→ 상속보다 *조합*이 일반적. `Lotto(val numbers: LottoNumbers)`.
|
|
54
|
+
|
|
55
|
+
### 5. `LottoNumber.Companion` private — 이유?
|
|
56
|
+
|
|
57
|
+
> companion object를 private으로 만든 이유가 있나요?
|
|
58
|
+
|
|
59
|
+
→ private companion = 외부에서 LottoNumber.of() 같은 팩토리 호출 불가. 의도였는지 실수였는지.
|
|
60
|
+
|
|
61
|
+
## 얻은 교훈
|
|
62
|
+
|
|
63
|
+
- **UX 친화 입력 처리** — `1,2,3,4,5,6` vs `1, 2, 3, 4, 5, 6` 둘 다 받기. trim()으로.
|
|
64
|
+
- **상속 vs 조합** — 코드 중복 회피로 상속 도입은 위험. 보통 조합이 더 안전.
|
|
65
|
+
- **두 클래스가 거의 같다 = 합칠 후보**. 역할이 다르면 *분명한 메서드 차이*가 있어야.
|
|
66
|
+
- **`private companion object`** — 팩토리 메서드 노출 차단. 의도면 OK, 실수면 수정.
|