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,187 @@
|
|
|
1
|
+
# PR #52 — [멧돼지] 2단계 로또
|
|
2
|
+
|
|
3
|
+
- **Reviewee:** [@2chang5](https://github.com/2chang5)
|
|
4
|
+
- **PR:** https://github.com/woowacourse/kotlin-lotto/pull/52
|
|
5
|
+
- **단계:** 2단계 (수동 로또 추가)
|
|
6
|
+
- **리뷰어:** @laco-dev (페로로)
|
|
7
|
+
- **라인 코멘트:** 19
|
|
8
|
+
|
|
9
|
+
## 잘한 점 (설계 관점)
|
|
10
|
+
|
|
11
|
+
- **`LottoNumber` `value class`** — 인라인 클래스 활용.
|
|
12
|
+
- **`ManualPurchaseCount` value class + private constructor + factory** — 검증 강제.
|
|
13
|
+
- **`LottoFactory` 인터페이스 + `RandomLottoFactory`/`ManualLottoFactory`** — Strategy.
|
|
14
|
+
- **자가 의문 PR에 풍부히 명시** — *Manual Factory가 InputView를 의존*하는 딜레마를 학생이 직접 정리.
|
|
15
|
+
|
|
16
|
+
## 못한 점 (설계 관점)
|
|
17
|
+
|
|
18
|
+
### 1. `purchaseLottoCount` + `purchaseLotto` 분할 입력 — 학생 의도 의문
|
|
19
|
+
|
|
20
|
+
```kotlin
|
|
21
|
+
private fun getManualPurchaseCount(purchaseCount: Int): ManualPurchaseCount {. }
|
|
22
|
+
private fun getManualPurchaseLotto(manualPurchaseCount: ManualPurchaseCount): List<Lotto> {. }
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
리뷰어: "InputView로부터 purchaseLottoCount(), purchaseLotto()를 *나눠서 호출하는 이유*는 무엇인가요?" 학생: "*입력을 각각 따로 받기*도 하고 한 함수에서 *한 가지 일만* 하려고 노력하는 방향에서 쪼개 보았습니다! 로또를 *구입 금액을 입력*하는 것과 *로또 발행을 구분*한 것처럼 수동 로또 *구입 갯수와 수동 로또 입력을 구분*하였습니다!"
|
|
26
|
+
|
|
27
|
+
### 2. bonus 확인에 `map` 불필요
|
|
28
|
+
|
|
29
|
+
```kotlin
|
|
30
|
+
fun matchLottoNumber(bonusNumber: LottoNumber): Boolean =
|
|
31
|
+
bonusNumber.value in lottoNumbers.map { lottoNumber -> lottoNumber.value } // ⚠ map
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
리뷰어: "bonusNumber가 있는지 확인하기 위해, *map으로 변환할 필요는 없습니다*. 앞서 사용한 `count {. }` 함수를 잘 활용해 보세요" 학생: "count를 활용하여 리팩토링해 보았지만 뭔가 `in`을 사용하면 *안에 있나 없나가 직관적*으로 받아들여지는 반면 count를 사용하면 *뭔가 한참 생각해야 아 이게 안에 존재하는지 판별*하는구나를 느낄 수 있는 거 같아 저는 뭔가 아쉬운데…" 리뷰어 답: "map과 in이 따로 있어서 헷갈렸군요. 이 경우에는 *`any { }` 함수*를 사용할 수 있을 것 같아요." — `any { it == bonusNumber }`.
|
|
35
|
+
|
|
36
|
+
### 3. 같은 클래스 파라미터는 private 함수 접근 가능
|
|
37
|
+
|
|
38
|
+
```kotlin
|
|
39
|
+
fun countContainLottoNumber(lotto: Lotto): Int =
|
|
40
|
+
lottoNumbers.count { lottoNumber -> lottoNumber.value in lotto.lottoNumbers.map { it.value } }
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
리뷰어: "위 함수에서 `lotto.lottoNumbers.map` 함수는 *몇 번이 호출*이 될까요? 메소드의 *파라미터로 같은 클래스가 들어온다면, private 함수를 호출*할 수 있습니다." — `lottoNumbers.count { it in other.lottoNumbers }`로, *내부 직접 접근*.
|
|
44
|
+
|
|
45
|
+
### 4. `ManualPurchaseCount`가 `purchaseCount`까지 검증
|
|
46
|
+
|
|
47
|
+
```kotlin
|
|
48
|
+
value class ManualPurchaseCount private constructor(val value: Int) {
|
|
49
|
+
init { require(value > 0) }
|
|
50
|
+
companion object {
|
|
51
|
+
fun ManualPurchaseCount(manualPurchaseCount: Int, purchaseCount: Int): ManualPurchaseCount {
|
|
52
|
+
require(manualPurchaseCount < purchaseCount) { BIGGER_MANUAL_PURCHASE_MONEY_ERROR }
|
|
53
|
+
return ManualPurchaseCount(manualPurchaseCount)
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
리뷰어: "'수동 로또 수'가 '구입 로또 수'에 *관심을 가지는 게 맞는 설계*일까요? 구조적으로 고려한다면 아래 형태로, *하나의 묶음으로서 관리*가 되어야 하지는 않을까요?
|
|
60
|
+
```
|
|
61
|
+
전체 구매 갯수 {
|
|
62
|
+
수동 구매 갯수
|
|
63
|
+
자동 구매 갯수
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
즉, 현재 구조에서 *아래 함수는 논리적으로 문제가 되지 않는 코드*가 됩니다.
|
|
67
|
+
```kotlin
|
|
68
|
+
val totalCount = 20
|
|
69
|
+
val autoCount = 5
|
|
70
|
+
val manualCount = ManualPurchaseCount(15, totalCount)
|
|
71
|
+
doNext(manualCount, autoCount) // 잘못 넣음 그런데 전혀 문제가 없음
|
|
72
|
+
```" — *팩토리에서 전체 수를 받아도 인스턴스에는 안 남으므로* 외부에서 *서로 모순된 값*을 넘길 수 있음.
|
|
73
|
+
|
|
74
|
+
### 5. `Fake Constructor` 이름 패턴
|
|
75
|
+
|
|
76
|
+
```kotlin
|
|
77
|
+
companion object {
|
|
78
|
+
fun ManualPurchaseCount(manualPurchaseCount: Int, purchaseCount: Int): ManualPurchaseCount {. }
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
리뷰어: "프로덕션 코드에서 사용할 목적으로는 *Fake Constructor와 같이 대문자로 시작하는 함수*를 사용하는 경우는 특이한 경우를 제외하고는 없습니다. *명시적으로 함수에 이름을 부여*하도록 해야 합니다." — `of(.)` 또는 `from(.)`.
|
|
83
|
+
|
|
84
|
+
### 6. Controller가 *자동/수동 발행 정책*을 다 알고 있음
|
|
85
|
+
|
|
86
|
+
```kotlin
|
|
87
|
+
private fun getLottoBunch(
|
|
88
|
+
purchaseCount: Int,
|
|
89
|
+
manualPurchaseCount: ManualPurchaseCount,
|
|
90
|
+
manualPurchaseLotto: List<Lotto>,
|
|
91
|
+
): LottoBunch {
|
|
92
|
+
val autoPurchaseCount = getAutoPurchaseCount(purchaseCount, manualPurchaseCount)
|
|
93
|
+
val lottoBunch = LottoBunch(manualPurchaseLotto + List(autoPurchaseCount) { lottoFactory.createLotto() })
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
리뷰어: "무언가 *어색함*이 느껴지지는 않으셨나요? 자동 로또는 *로또 팩토리를 이용*해서 만들고 있습니다. 수동 로또는 *직접 만들고* 있습니다. 즉, 현재는 LottoFactory라는 타입이 *랜덤으로 줄 것이다라는 것을 컨트롤러가 이미 전부 다 알고 있다*는 의미가 됩니다. *자동으로 만들지, 수동으로 만들지 구체적인 방법은 구현체에서 결정*해야 하지 않을까요? 의존성을 주입하는 방법은 크게 3가지: 1. 생성자 2. ??? 3. ???"
|
|
98
|
+
|
|
99
|
+
### 7. `ManualLottoFactory`의 *View 의존* 딜레마
|
|
100
|
+
|
|
101
|
+
```kotlin
|
|
102
|
+
class ManualLottoFactory : LottoFactory {
|
|
103
|
+
override fun createLotto(): Lotto =
|
|
104
|
+
Lotto(InputView.getManualPurchaseLotto().map { LottoNumber(it) }.toSet()) // ⚠ View 의존
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
리뷰어: "ManualLotto에서 InputView에 의존해서 직접 가져오도록 한 방법은 좋습니다. 하지만 *도메인에서 view를 의존하게 되면 안* 됩니다. 도메인에서 구현해야 하는 대상이 맞다면, *뷰에 의존하지 않는 다른 형태*로 만들거나, *컨트롤러가 있는 곳에서 구현*을 해야 맞겠습니다." 학생 자가 의문 길게: "*createLotto에 인자를 추가*하는 방법, *인터페이스에 별도 메서드 추가*, *setter/생성자로 상태 보유* — 셋 다 마음에 안 들어요." 리뷰어: "1번, 2번, 3번 *모두 좋지 않은 방법*입니다. 이 내용은 지금 단계에서는 *고민하는 것으로 충분한 도움*이 되셨을 것 같습니다. 저는 지금 *제 의견이나 답을 알려드리지 않을 건데요*. 이렇게도 구현해 보고, 저렇게도 구현해 보고 *스스로 답을 찾아*가셨으면 좋겠습니다." — *명확한 정답이 없는* 영역에서 학생이 직접 시도.
|
|
109
|
+
|
|
110
|
+
### 8. `LottoBunch.from(totalPurchaseCount)`이 *슈퍼 함수*가 됨
|
|
111
|
+
|
|
112
|
+
```kotlin
|
|
113
|
+
class LottoBunch(val value: List<Lotto>) {
|
|
114
|
+
companion object {
|
|
115
|
+
fun from(totalPurchaseCount: TotalPurchaseCount): LottoBunch {
|
|
116
|
+
val lottoBunch = LottoBunch(getManualPurchaseLotto(.) + getAutoPurchaseLotto(.))
|
|
117
|
+
OutputView.printPurchaseResult(.) // ⚠ View 호출
|
|
118
|
+
return lottoBunch
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
리뷰어: "LottoBunch가 *직접적으로 로또 구현 방식을 알게 되면서*, 지금까지 쌓아온 방식이 *모두 깨진 것* 같습니다.
|
|
125
|
+
1. *도메인에서 UI 구현*을 하고 있습니다.
|
|
126
|
+
2. 도메인에서 *자동 팩토리, 수동 팩토리와 모두 의존*하게 되었습니다.
|
|
127
|
+
3. *LottoBunch.from 함수가 슈퍼 함수*가 되었습니다. 모든 게임의 로직을 담고 있게 되었네요." 학생: "아아아아아아아아 컨트롤러가 어떤 조건인지 *모르게 하려고 옮겼는데 더 중요한 규칙을 어겨버렸*네요. 다 알고 숙지한 내용인데 왜 이런 바보짓을 했는지 부끄럽습니다. 그래도 오히려 바보짓을 많이 해서 좀 더 *각인되게 룰을 배우는 것* 같습니다!!"
|
|
128
|
+
|
|
129
|
+
### 9. `AutoPurchaseCount` — 단순 복붙
|
|
130
|
+
|
|
131
|
+
```kotlin
|
|
132
|
+
value class AutoPurchaseCount(val value: Int) {
|
|
133
|
+
init { require(value > 0) { NEGATIVE_AUTO_PURCHASE_MONEY_ERROR } }
|
|
134
|
+
companion object { private const val NEGATIVE_AUTO_PURCHASE_MONEY_ERROR = "수동 구입 로또수는 음수일 수 없습니다" } // ⚠ 메시지가 수동
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
리뷰어: "PurchaseCount가 *두 개로 만들어질 이유*가 있을지는 모르겠네요. 그럼에도 만들었으니 의견을 드려보면. *수동 로또에서 복사 붙여넣기 한 것* 같습니다." — 메시지에 *수동 로또*라는 문구가 남아 있음.
|
|
139
|
+
|
|
140
|
+
### 10. `TotalPurchaseCount`의 주생성자가 Int
|
|
141
|
+
|
|
142
|
+
```kotlin
|
|
143
|
+
class TotalPurchaseCount(totalPurchaseCount: Int, manualPurchaseCount: Int) {
|
|
144
|
+
val autoPurchaseCount: AutoPurchaseCount
|
|
145
|
+
val manualPurchaseCount: ManualPurchaseCount
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
리뷰어: "Int 타입으로 만든다고 하면, *PurchaseCount를 받는 게 주 생성자*가 되어야 하지 않을까요? 부 생성자를 이용해서 만들어 볼 수도 있겠습니다. 검증은 생성 이후의 *init 블록*에서 해도 괜찮지 않을까 싶어요" — *주 생성자*에 *value class* 받는 것이 자연.
|
|
150
|
+
|
|
151
|
+
## 리뷰어 의견 요지
|
|
152
|
+
|
|
153
|
+
- **단계별 입력 분리** — *한 함수 한 역할* 원칙. 입력의 *의미 단위*로 분리.
|
|
154
|
+
- **`map().contains()` → `any {}`** — Kotlin idiomatic.
|
|
155
|
+
- **같은 클래스 파라미터는 *내부 접근* 가능** — `private` 멤버를 직접 사용.
|
|
156
|
+
- **상위 객체에서 두 개수를 함께 관리** — `ManualCount + AutoCount`보다 `TotalPurchaseCount`로 묶기.
|
|
157
|
+
- **`Fake Constructor` 회피** — `of`/`from` 같은 *명시적 이름*.
|
|
158
|
+
- **Controller가 자동/수동 정책 X** — 구현체에서 결정.
|
|
159
|
+
- **도메인 → View 의존 금지** — Manual 입력 → Controller에서 데이터 받고 → Factory에 인자로 넘기는 방법은 *학생이 직접 답 찾을 영역*.
|
|
160
|
+
- **`LottoBunch`가 발행+출력+팩토리 의존 모두 흡수** = *슈퍼 함수* 안티패턴.
|
|
161
|
+
|
|
162
|
+
- **대표 인용:**
|
|
163
|
+
> '수동 로또 수'가 '구입 로또 수'에 *관심을 가지는 게 맞는 설계*일까요? 구조적으로 고려한다면 *하나의 묶음으로서 관리*가 되어야 하지는 않을까요?
|
|
164
|
+
> — @laco-dev on `src/main/kotlin/lotto/domain/ManualPurchaseCount.kt`
|
|
165
|
+
|
|
166
|
+
> 자동 로또는 *로또 팩토리를 이용*해서 만들고 있습니다. 수동 로또는 *직접 만들고* 있습니다. … *컨트롤러가 이미 전부 다 알고 있다*는 의미가 됩니다.
|
|
167
|
+
> — @laco-dev on `src/main/kotlin/lotto/LottoController.kt`
|
|
168
|
+
|
|
169
|
+
> LottoBunch가 직접적으로 로또 구현 방식을 알게 되면서, 지금까지 쌓아온 방식이 *모두 깨진 것* 같습니다. … *LottoBunch.from 함수가 슈퍼 함수*가 되었습니다.
|
|
170
|
+
> — @laco-dev on `src/main/kotlin/lotto/domain/LottoBunch.kt`
|
|
171
|
+
|
|
172
|
+
> 1번, 2번, 3번 *모두 좋지 않은 방법*입니다. … 저는 지금 *제 의견이나 답을 알려드리지 않을* 건데요. 이렇게도 구현해 보고, 저렇게도 구현해 보고 *스스로 답을 찾아*가셨으면 좋겠습니다.
|
|
173
|
+
> — @laco-dev on `src/main/kotlin/lotto/domain/factory/ManualLottoFactory.kt`
|
|
174
|
+
|
|
175
|
+
## 얻은 교훈
|
|
176
|
+
|
|
177
|
+
- **한 함수 한 역할** — 입력의 *의미 단위*로 분리.
|
|
178
|
+
- **Kotlin idiomatic**: `map().contains()`보다 `any {}`/`count {}`로 한 번 순회.
|
|
179
|
+
- **같은 클래스 파라미터** = *private 멤버 직접 접근* 가능 — `Lotto.match(other: Lotto)` 안에서 `other.numbers`.
|
|
180
|
+
- **상위 객체로 묶기** — `ManualCount(value, total)`은 *total을 안 가지므로* 모순 가능. `TotalPurchaseCount`에 `manual + auto` 묶으면 invariant 강제.
|
|
181
|
+
- **`Fake Constructor`(대문자 함수) 회피** — `of`/`from`/`create` 같은 *명시적 이름*.
|
|
182
|
+
- **Controller는 *발행 정책*을 모르게**. 자동/수동 분기를 Controller가 알면 *구현체의 의미 소실*.
|
|
183
|
+
- **도메인 → View 의존 금지** — 학생의 *3가지 시도 모두 거절*되는 영역. *해결책은 스스로 찾기*가 학습.
|
|
184
|
+
- **`LottoBunch.from`이 *슈퍼 함수*가 되는 신호** — *발행 + 출력 + 팩토리 의존*이 한 함수에 모이면 도메인의 의미가 깨짐. *돌이켜 보면 다 알던 규칙*인데 *과정에서 실수*함을 학생이 자가 인정.
|
|
185
|
+
- **PurchaseCount 응집 클래스** — Total/Manual/Auto를 *한 곳*에서 관리.
|
|
186
|
+
- **value class의 주생성자에 *value class*** — 부생성자가 *Int 변환*을 수행하고 *init에서 검증*.
|
|
187
|
+
- **메시지 복붙 검토** — *AutoPurchaseCount*에 *수동 로또* 메시지가 남으면 *복사 흔적*.
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
# PR #14 — [로피] 1단계 로또
|
|
2
|
+
|
|
3
|
+
- **Reviewee:** [@Choisehyeon](https://github.com/Choisehyeon)
|
|
4
|
+
- **PR:** https://github.com/woowacourse/kotlin-lotto/pull/14
|
|
5
|
+
- **단계:** 1단계
|
|
6
|
+
- **리뷰어:** @malibinYun (말리빈)
|
|
7
|
+
- **라인 코멘트:** 36 (리뷰어 33 + 학생 3)
|
|
8
|
+
|
|
9
|
+
## 잘한 점 (설계 관점)
|
|
10
|
+
|
|
11
|
+
- **`LottoNumber` 캐싱 (Flyweight)** — 칭찬: "*숫자 캐싱을 잘 해 주셨네요* 👍👍".
|
|
12
|
+
|
|
13
|
+
## 못한 점 (설계 관점)
|
|
14
|
+
|
|
15
|
+
### 1. `LottoNumber` *객체화 부재*
|
|
16
|
+
|
|
17
|
+
리뷰어: "*로또 번호를 하나의 객체로 표현*해 보는 것은 어떨까요?" — 원시 Int 사용.
|
|
18
|
+
|
|
19
|
+
### 2. `matchLottos`가 *Lotto + Lottos 양쪽* — 중복 책임
|
|
20
|
+
|
|
21
|
+
```kotlin
|
|
22
|
+
class Lotto { fun matchLottos(.) =. }
|
|
23
|
+
class Lottos { fun matchLottos(.) =. } // ⚠ 중복
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
리뷰어: "matchLottos는 *Lotto에도 있고, Lottos에도 있*네요! *winningLotto와 bonusNumber를 묶어서 당첨 티켓이란 객체를 만들어 보는 것*은 어떨까요?"
|
|
27
|
+
|
|
28
|
+
### 3. `WinningResult` *빈 껍데기 + 외부 채우기* — invariant 시간차
|
|
29
|
+
|
|
30
|
+
```kotlin
|
|
31
|
+
val result = WinningResult()
|
|
32
|
+
lottos.forEach {. result.add(rank). } // ⚠ 외부 조립
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
리뷰어: "*빈 껍데기의 WinningResult를 만들어서 값을 채우기보다, WinningResult를 직접 만들어서 반환*하는 것은 어떨까요?" — *invariant 시간차*: 생성 시점엔 *불완전 객체*. 사용 시점엔 *완전 객체*. *Tell-Don't-Ask* 위반.
|
|
36
|
+
|
|
37
|
+
### 4. *갯수 세는 확장 함수* — `count { }` 활용
|
|
38
|
+
|
|
39
|
+
리뷰어: "*갯수를 세어 주는 확장 함수를 찾아 보는 것은* 어떨까요?" → `Iterable.count { predicate }`.
|
|
40
|
+
|
|
41
|
+
### 5. *Rank에 View 로직*
|
|
42
|
+
|
|
43
|
+
리뷰어: "도메인에 *View에 대한 로직이 들어 있*네요. *View에 대한 로직은 View에서만 사용*해 주세요!" — 모든 PR 공통 패턴.
|
|
44
|
+
|
|
45
|
+
### 6. `Rank` *2등을 먼저 검사* — 순서 의존
|
|
46
|
+
|
|
47
|
+
리뷰어: "*rank를 찾기 전에 2등을 먼저 검사해 보는 것은 어떨까요*?" — *bonus = 5등급 동률 시 2등 분기*. *find 순서*에 *비즈니스 의도*.
|
|
48
|
+
|
|
49
|
+
### 7. *로또 생성을 View가 함*
|
|
50
|
+
|
|
51
|
+
리뷰어: "*로또를 만들어 내는 것은 View의 역할일까요*? 😀"
|
|
52
|
+
|
|
53
|
+
### 8. *테스트 공유 변수*
|
|
54
|
+
|
|
55
|
+
리뷰어: "*여러 테스트가 하나의 변수를 공유하면 어떤 장단점*이 있을까요?" — *테스트 격리* vs *공통 fixture*.
|
|
56
|
+
|
|
57
|
+
### 9. *랜덤 테스트 제어* — 자동차 경주 학습
|
|
58
|
+
|
|
59
|
+
리뷰어: "*자동차 경주 미션을 잘 상기해서, 랜덤에 대한 테스트를 다시 구현*해 보세요! *랜덤 요소를 개발자가 제어 가능하게 만들어 보는 것을 고민*해 주세요 🙂" — *Random 외부 주입* 일관 가르침.
|
|
60
|
+
|
|
61
|
+
### 10. *어떤 메시지가 나왔는지* — 출력 검증
|
|
62
|
+
|
|
63
|
+
리뷰어: "*어떤 메시지가 나왔는지도 검증*해 보는 건 어떨까요? 🙂" — *경로만 테스트 X, 출력 내용도*.
|
|
64
|
+
|
|
65
|
+
### 11. *생성자 위치* — Kotlin 컨벤션
|
|
66
|
+
|
|
67
|
+
리뷰어: "*생성자의 위치는 멤버 함수들 가장 상위에 위치하는 것이 [코틀린 컨벤션](https://kotlinlang.org/docs/coding-conventions.html#class-layout)*입니다 :)"
|
|
68
|
+
|
|
69
|
+
### 12. *`(1..count).map`* / *`List() { }` 가짜 생성자* — `forEach` 누적 대안
|
|
70
|
+
|
|
71
|
+
리뷰어: "*(1..count).map { ~ } 이런 확장 함수를 활용*해 보시길 의도했어요. 🙂 *List() { ~ } 같은 전역 함수를 활용*해 보셔도 좋습니다. *다른 반복문을 통해 Collection을 만들어 내는 부분들도 확장 함수로 바꿔 보는 것을 도전*해 보세요 💪"
|
|
72
|
+
|
|
73
|
+
### 13. *생성자에서 프로퍼티*
|
|
74
|
+
|
|
75
|
+
리뷰어: "*바로 생성자에서 프로퍼티를 생성*해 보는 것은 어떨까요?" — 본문 init보다 *주 생성자 val* 명시.
|
|
76
|
+
|
|
77
|
+
### 14. `String` `+` 결합
|
|
78
|
+
|
|
79
|
+
리뷰어: "*String을 +로 만드는 것은 지양*해야 합니다. 지금은 *컴파일러가 똑똑해져서 알아서 효율적으로 바꿔 주지만, 어떤 단점이 있었을까요*?" — *불변 문자열 매번 생성*. `StringBuilder`/template.
|
|
80
|
+
|
|
81
|
+
### 15. *메서드 체이닝 줄 분리*
|
|
82
|
+
|
|
83
|
+
리뷰어: "*메서드 체이닝할 때는 한 줄에 하나만 사용해 보는 것은 어떨까요*? *붙여 썼을 때 어떤 문제가 생길 수* 있을까요?" + "*체이닝된 메서드 중 한 곳에서 Exception이 발생하면, 콘솔에서는 해당 라인을 가리킵니다. 한 줄로 되어 있다면, 어떤 체이닝된 곳에서 Exception이 발생했는지 찾기 어려워*지겠지요 🙂" — *디버깅 가독성*.
|
|
84
|
+
|
|
85
|
+
### 16. `entries` vs `values()`
|
|
86
|
+
|
|
87
|
+
리뷰어: "*이전처럼 values()를 활용*해 보세요!" — Kotlin 1.9+ `entries`.
|
|
88
|
+
|
|
89
|
+
### 17. `WinningLotto` 빈 객체 — 역할 위임
|
|
90
|
+
|
|
91
|
+
리뷰어: "List<LottoNumber> 대신 *Lotto를 재활용*해 보는 건 어떨까요? 또, *Winning Lotto 객체는 값을 갖고 있기만 할 뿐, 아무 역할도 하고 있지 않고 있*어요. *다른 곳에 흩어져 있는 적절한 역할을 이 객체에 위임*해 보아요 😊"
|
|
92
|
+
|
|
93
|
+
### 18. *`String?.nullOrBlank()`* 활용
|
|
94
|
+
|
|
95
|
+
리뷰어: "*String?.nullOrBlank() 확장 함수를 활용*해 보세요" — Kotlin stdlib.
|
|
96
|
+
|
|
97
|
+
### 19. *주석으로 테스트 횟수 표시* — 거짓말 위험
|
|
98
|
+
|
|
99
|
+
리뷰어: "*주석을 활용하는 것은 완전히 나쁜 방법은 아니라고* 생각해요. 다만, *주석은 코드가 변경 돼도 에러를 뱉어 내지 않기 때문에 수정하지 않게 되고, 거짓말을 할 가능성이 매우 높아져 주의*해야겠지요. 🙂 *반복 테스트를 할 때 정말로 횟수가 의미가 있는 지 먼저 생각*해 보시면 좋겠어요. *단순히 값만 바꾼 같은 경우의 반복 테스트는, 정말 의미가 있을까요? 어떤 경우가 반복했을 때 의미 있는 테스트가 될까요*?"
|
|
100
|
+
|
|
101
|
+
### 20. *너무 긴 검증문*
|
|
102
|
+
|
|
103
|
+
리뷰어: "*검증문이 너무 길어 읽기 어렵습니다. 메시지는 변수에 할당해 보는 것은* 어떨까요?"
|
|
104
|
+
|
|
105
|
+
### 21. *변하지 않는 검증 재료* 파라미터?
|
|
106
|
+
|
|
107
|
+
리뷰어: "*변하지 않는 검증 재료를 파라미터로 받을 필요가 있을까요*?"
|
|
108
|
+
|
|
109
|
+
### 22. *ParameterizedTest인데 1번만 테스트*
|
|
110
|
+
|
|
111
|
+
리뷰어: "*ParameterizedTest인데 테스트는 실제로 1번만 하고 있*네요. *ParameterizedTest일 필요가 있을지 고민*해 보아요 :)" — *애너테이션 오용*.
|
|
112
|
+
|
|
113
|
+
### 23. *`Set` 활용 — 중복 방지*
|
|
114
|
+
|
|
115
|
+
리뷰어: "*Set을 활용*해 보는 것은 어떨까요?".
|
|
116
|
+
|
|
117
|
+
### 24. *양방향 의존* — `Lotto` ↔ `WinningLotto`
|
|
118
|
+
|
|
119
|
+
```kotlin
|
|
120
|
+
class Lotto { fun matchWith(winning: WinningLotto) =. }
|
|
121
|
+
class WinningLotto { fun matchWith(lotto: Lotto) =. } // ⚠
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
리뷰어: "*Lotto와 WinningLotto가 서로 알고 있는 양방향 의존성을 지니*네요. *양방향 의존 관계는 어떤 단점이 있을까요*? matchLotto 역할의 위치를 다시 한 번 생각해 볼까요? 🙂" — *순환 의존*은 *변경 전파*.
|
|
125
|
+
|
|
126
|
+
### 25. `LottoGame.matchGame` — 어색한 이름
|
|
127
|
+
|
|
128
|
+
리뷰어: "*LottoGame의 이름과 실제 하는 역할에 대해 충분히 고민*해 보셨으면 좋겠어요. *matchGame은 다른 개발자가 봤을 때에도 한 번에 이해되는 이름일까요*?"
|
|
129
|
+
|
|
130
|
+
### 26. *generate마다 1..45 리스트 매번 생성*
|
|
131
|
+
|
|
132
|
+
```kotlin
|
|
133
|
+
fun generate(): List<Int> = (1..45).shuffled().take(6) // ⚠ 매번 새 리스트
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
리뷰어: "*generate를 할 때마다 1~45 숫자 list가 매번 생성*되겠네요. *한 번만 만들어 보는 것은 어떨까요*?" — *상수 컬렉션*으로 *재사용*.
|
|
137
|
+
|
|
138
|
+
### 27. *피드백 롤백 오해* — 학생의 오해
|
|
139
|
+
|
|
140
|
+
리뷰어: "*[이전처럼 변경]해 보라는 의미는 [이전에 드렸던 피드백]까지도 이전으로 롤백하라는 의미가 아닙니다*. 😥" — *부분 변경 의도*가 *전체 롤백*으로 오해된 경우.
|
|
141
|
+
|
|
142
|
+
### 28. `WinningLotto.hasBonusNumber()` — *어색*
|
|
143
|
+
|
|
144
|
+
리뷰어: "이 메서드들은 *당첨 로또가 가져야 할 일이 맞을까요*? *당첨 티켓은 반드시 보너스 볼을 지니는데*, 특히, *WinningLotto.hasBonusNumber()는 굉장히 어색한 사용*으로 느껴집니다." — *항상 true*인 메서드는 *불필요*.
|
|
145
|
+
|
|
146
|
+
### 29. *테스트 준비 = `Lotto(1, 2, 3, 4, 5, 6)`*
|
|
147
|
+
|
|
148
|
+
리뷰어: "테스트의 *준비 재료를 map 등의 로직으로 만들어 내는 것은 가독성을 해칩니다*. 아래 코드 스니펫을 참고해서, *생성자 혹은 가짜 생성자(팩토리 함수)로 만들어 보는 것*은 어떨까요?
|
|
149
|
+
```kotlin
|
|
150
|
+
val lotto = Lotto(1, 2, 3, 4, 5, 6)
|
|
151
|
+
```".
|
|
152
|
+
|
|
153
|
+
### 30. *ParameterizedTest 도전* — CsvSource
|
|
154
|
+
|
|
155
|
+
리뷰어: "이 테스트는 *PrameterizedTest로 만들어 보는 것을 도전*해 보세요! 💪 힌트로, *CsvSource를 활용*해 보세요 :)"
|
|
156
|
+
|
|
157
|
+
## 리뷰어 의견 요지
|
|
158
|
+
|
|
159
|
+
- **`LottoNumber` 객체화 + Set**.
|
|
160
|
+
- **`matchLottos` 양쪽 중복 → 당첨 티켓**.
|
|
161
|
+
- **빈 객체 + 외부 채우기 → *완성 객체 반환***.
|
|
162
|
+
- **`Rank.from` 2등 우선 분기**.
|
|
163
|
+
- **View vs 도메인 = 모든 PR 공통**.
|
|
164
|
+
- **랜덤 외부 주입** (자동차 경주 학습).
|
|
165
|
+
- **출력 메시지도 검증**.
|
|
166
|
+
- **Kotlin 컨벤션 *생성자 위치, 체이닝 줄 분리***.
|
|
167
|
+
- **`String +` → 템플릿**.
|
|
168
|
+
- **양방향 의존 = 순환 위험**.
|
|
169
|
+
- **`hasBonusNumber()` 항상 true** = 불필요.
|
|
170
|
+
- **`ParameterizedTest` *1번만*** = 오용.
|
|
171
|
+
- **테스트 준비 = *생성자/팩토리***. `map` 로직 가독성 해침.
|
|
172
|
+
- **주석 = *거짓말 가능성*** — 코드 변경에 따라가지 않음.
|
|
173
|
+
- **`(1..45).shuffled()` *매번 생성*** → 상수 컬렉션 재사용.
|
|
174
|
+
|
|
175
|
+
- **대표 인용:**
|
|
176
|
+
> 빈 껍데기의 WinningResult를 만들어서 값을 채우기보다, *WinningResult를 직접 만들어서 반환*하는 것은 어떨까요?
|
|
177
|
+
> — @malibinYun on `src/main/kotlin/lotto/domain/WinningResult.kt`
|
|
178
|
+
|
|
179
|
+
> 주석은 *코드가 변경 돼도 에러를 뱉어 내지 않기 때문에 수정하지 않게 되고, 거짓말을 할 가능성이 매우 높아*져 주의해야겠지요.
|
|
180
|
+
> — @malibinYun on `src/test/kotlin/lotto/domain/LottoTest.kt`
|
|
181
|
+
|
|
182
|
+
> 당첨 티켓은 반드시 보너스 볼을 지니는데, 특히, *WinningLotto.hasBonusNumber()는 굉장히 어색한 사용*으로 느껴집니다.
|
|
183
|
+
> — @malibinYun on `src/main/kotlin/lotto/domain/WinningLotto.kt`
|
|
184
|
+
|
|
185
|
+
> 양방향 의존 관계는 *어떤 단점*이 있을까요?
|
|
186
|
+
> — @malibinYun on `src/main/kotlin/lotto/domain/Lotto.kt`
|
|
187
|
+
|
|
188
|
+
## 얻은 교훈
|
|
189
|
+
|
|
190
|
+
- **빈 객체 + 외부 채우기 = *invariant 시간차*** — 생성 시점에 *불완전*. *완성된 객체 반환*이 *invariant 즉시 보장*.
|
|
191
|
+
- **`matchLottos` *양쪽 중복*** = 책임 위치 모호. *WinningLotto*가 *매칭 진입점*.
|
|
192
|
+
- **`Rank.from` 분기 순서 = *비즈니스 의도*** — *2등 먼저 검사*가 *bonus 동률 처리* 명세.
|
|
193
|
+
- **양방향 의존 = *순환 위험 + 변경 전파*** — `Lotto.match(winning)` 또는 `winning.match(lotto)` 한쪽만.
|
|
194
|
+
- **`hasBonusNumber()` *항상 true* = 불필요** — *invariant인 속성*은 *질문할 필요 없음*.
|
|
195
|
+
- **`ParameterizedTest` *1번만*** = 잘못된 도구. *vanilla `@Test`* 충분.
|
|
196
|
+
- **테스트 준비 = *생성자/팩토리*** — `numbers.map {. }`보다 *Lotto(1,2,3,4,5,6)*가 *의도 즉시*.
|
|
197
|
+
- **주석의 *거짓말 위험*** — *컴파일러가 검증 안 함*. 코드 변경에 따라가지 않음.
|
|
198
|
+
- **반복 테스트 *의미 있는 횟수*** — *값만 바꾸는 반복*은 *시그널 없음*. *경계값/엣지 케이스*가 의미 있는 반복.
|
|
199
|
+
- **`(1..45).shuffled()` *매번 생성*** → *상수 컬렉션 재사용*. *Flyweight*의 변형.
|
|
200
|
+
- **생성자 위치 = *멤버 함수 가장 상위*** — Kotlin 컨벤션.
|
|
201
|
+
- **체이닝 *줄 분리*** = *디버깅 가독성*. *Exception 라인 추적*.
|
|
202
|
+
- **`String +` → *템플릿/StringBuilder*** — *불변 문자열* 매번 생성.
|
|
203
|
+
- **랜덤 외부 주입** — *자동차 경주 학습*. 일관된 가르침.
|
|
204
|
+
- **출력 메시지 검증** — *경로 통과만으로 부족*. *어떤 내용이 출력되었는지*도.
|
|
205
|
+
- **`(1..count).map { gen() }` / `List(n) { gen() }`** — Kotlin idiom.
|
|
206
|
+
- **`String?.isNullOrBlank()` *Kotlin stdlib*** 활용.
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
# PR #47 — [로피] 2단계 로또
|
|
2
|
+
|
|
3
|
+
- **Reviewee:** [@Choisehyeon](https://github.com/Choisehyeon)
|
|
4
|
+
- **PR:** https://github.com/woowacourse/kotlin-lotto/pull/47
|
|
5
|
+
- **단계:** 2단계 (수동 로또)
|
|
6
|
+
- **리뷰어:** @malibinYun (말리빈)
|
|
7
|
+
- **라인 코멘트:** 21 (리뷰어 18 + 학생 3)
|
|
8
|
+
|
|
9
|
+
## 잘한 점 (설계 관점)
|
|
10
|
+
|
|
11
|
+
- **`take` 확장 함수** — 칭찬: "take 확장 함수를 활용해 주셨네요 👍".
|
|
12
|
+
- **Kotlin delegation** — 1단계와 다른 시도.
|
|
13
|
+
- **확장함수 활용** — 칭찬: "*코틀린 확장함수를 잘 활용*해 주셨네요!".
|
|
14
|
+
- **`Parameterized Test`** — 칭찬: "*Parameterized Test를 잘 작성*해 주셨네요!".
|
|
15
|
+
|
|
16
|
+
## 못한 점 (설계 관점)
|
|
17
|
+
|
|
18
|
+
### 1. `!!` 사용
|
|
19
|
+
|
|
20
|
+
리뷰어: "*null과 non-null을 엄격히 구분하는 언어이니, !!의 사용은 지양*해 주세요.".
|
|
21
|
+
|
|
22
|
+
### 2. *LottoMachine 매번 new*
|
|
23
|
+
|
|
24
|
+
리뷰어: "*로또를 생성할 때마다 LottoMachine을 새로 생성하지 않고 재활용*할 수 있는 방법을 생각해 보아요 :)"
|
|
25
|
+
|
|
26
|
+
### 3. *결과 생성 책임 위치*
|
|
27
|
+
|
|
28
|
+
리뷰어: "*로또 결과를 생성하는 것은 어느 객체의 일일지* 다시 고민해 보아요 :)"
|
|
29
|
+
|
|
30
|
+
### 4. `Lotto delegation` *전체 인터페이스 노출*
|
|
31
|
+
|
|
32
|
+
```kotlin
|
|
33
|
+
class Lotto(numbers: List<LottoNumber>) : List<LottoNumber> by numbers
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
리뷰어: "*Kotlin Delegation을 활용해서 일급 컬렉션을 구현*해 주셨네요 :) delegation을 활용하면, *Lotto에서 필요한 메서드 뿐만 아니라 불필요한 메서드까지도 갖게* 됩니다. *일급 컬렉션에서는 필요한 메서드만 구현*해 보는 것은 어떨까요?".
|
|
37
|
+
|
|
38
|
+
### 5. *`List(n) {. }` 가짜 생성자*
|
|
39
|
+
|
|
40
|
+
리뷰어: "*List() {. }를 활용*해 볼 수 있어요 🙂" — 모든 PR 공통.
|
|
41
|
+
|
|
42
|
+
### 6. `Count` *많은 의존 + 책임 모호*
|
|
43
|
+
|
|
44
|
+
리뷰어: "이 *Count는 이름에 비해서 많은 의존 관계가 엮여 있어 보여요. Count라 하면 갯수만을 가지고 있을 것이 기대*되는데, *Money를 알고, Lotto를 간접적으로 알고 있는 형태*예요. 이 객체의 *역할과 책임에 대해서는 충분히 고민*을 해 보셨으면 좋겠어요. 너무 어려운 내용일 수도 있으니, *많은 변형을 하지 않으셔도 좋습니다* 🙂" — PR #140 (rosemin928) *LottoTicketCounter 책임 모호*와 같은 결.
|
|
45
|
+
|
|
46
|
+
### 7. *에러 메시지 정확성* — 보너스 번호 ≠ 로또 숫자
|
|
47
|
+
|
|
48
|
+
리뷰어: "*로또 숫자는 반드시 당첨 번호는 아니라고* 생각해요. *메시지를 더 다듬어 보는 건* 어떨까요?"
|
|
49
|
+
|
|
50
|
+
### 8. *`ParameterizedTest` + `MethodSource` 활용*
|
|
51
|
+
|
|
52
|
+
리뷰어: "이 테스트는 *Parameterized Test를 활용*해 볼 수 있겠네요 :)" + "*list처럼 복잡한 객체가 필요한 경우엔 Method Source가 더 적합*할 수 있어요 :)" + (한편) "*검증문에 필요한 비교군이 너무 길어 읽기 어렵습니다 :) 게다가 로직이 포함되어서 어떤 값이 반환될 지 한 번에 예측하기가 쉽지 않*아요. *검증의 비교군으로 들어가는 재료를 given 단계에서 미리 준비*해 두는 것은 어떨까요?"
|
|
53
|
+
|
|
54
|
+
### 9. *불필요한 코드*
|
|
55
|
+
|
|
56
|
+
리뷰어: "*필요하지 않는 코드는 지워* 주세요!"
|
|
57
|
+
|
|
58
|
+
### 10. `object` vs *한 번만 생성*
|
|
59
|
+
|
|
60
|
+
리뷰어: "*LottoMachine을 object를 활용해 만들어 주셨네요 :) 기존처럼 class로 두고, 필요한 곳에서 한 번만 생성해서 활용하는 방법도* 있답니다! *RandomLottoGenerator은 여전히 매번 만들어 줘야겠네요 :) 이 객체도 한 번만 만들고 재활용*해 보면 좋겠네요!"
|
|
61
|
+
|
|
62
|
+
### 11. *`asSequence` 활용*
|
|
63
|
+
|
|
64
|
+
리뷰어: "추가로, *.asSequence()에 대해 알아 보셔도 좋겠*어요 😊"
|
|
65
|
+
|
|
66
|
+
### 12. *`fun interface` + 람다*
|
|
67
|
+
|
|
68
|
+
리뷰어: "*fun interface에 대해 알아 보시고, 바로 람다로 넘기는 방법에 대해 알아*보시면 좋겠어요! 😊".
|
|
69
|
+
|
|
70
|
+
### 13. *when/then 혼재* — given/when/then 분리
|
|
71
|
+
|
|
72
|
+
리뷰어: "*when/then이 섞여 있어서 검증문이 길어*지네요 :) *저는 짧은 테스트라도 given when then을 모두 나눠 주는 게, 읽는 사람에게 더 잘 읽을 수 있게 도움을 준다*고 생각해요 🙂"
|
|
73
|
+
|
|
74
|
+
### 14. *`assertThat(Collection).hasSize()`*
|
|
75
|
+
|
|
76
|
+
리뷰어: "*assertThat(Collection).hasSize()를 활용*해 보세요 :)"
|
|
77
|
+
|
|
78
|
+
## 리뷰어 의견 요지
|
|
79
|
+
|
|
80
|
+
- **`!!` *마지막 수단***.
|
|
81
|
+
- **재활용 가능 객체 = *매번 new X***.
|
|
82
|
+
- **결과 생성 *책임 위치***.
|
|
83
|
+
- **`delegation` *전체 노출* → 일급 컬렉션 *선택 노출***.
|
|
84
|
+
- **`List(n) {. }`**.
|
|
85
|
+
- **`Count` *책임 응집*** — Money/Lotto 의존 X.
|
|
86
|
+
- **에러 메시지 *정확성***.
|
|
87
|
+
- **ParameterizedTest + MethodSource + given 단계 분리**.
|
|
88
|
+
- **`asSequence`** — 지연 평가.
|
|
89
|
+
- **`fun interface` 람다**.
|
|
90
|
+
- **given/when/then 분리**.
|
|
91
|
+
- **`hasSize()`** assertj idiom.
|
|
92
|
+
|
|
93
|
+
- **대표 인용:**
|
|
94
|
+
> delegation을 활용하면, Lotto에서 *필요한 메서드 뿐만 아니라 불필요한 메서드까지도 갖게* 됩니다. 일급 컬렉션에서는 *필요한 메서드만 구현*해 보는 것은 어떨까요?
|
|
95
|
+
> — @malibinYun on `src/main/kotlin/lotto/domain/Lotto.kt`
|
|
96
|
+
|
|
97
|
+
> 이 Count는 *이름에 비해서 많은 의존 관계가 엮여 있어 보여*요. Count라 하면 *갯수만을 가지고 있을 것이 기대*되는데, *Money를 알고, Lotto를 간접적으로 알고 있는 형태*예요.
|
|
98
|
+
> — @malibinYun on `src/main/kotlin/lotto/domain/Count.kt`
|
|
99
|
+
|
|
100
|
+
> 짧은 테스트라도 *given when then을 모두 나눠 주는 게, 읽는 사람에게 더 잘 읽을 수 있게 도움*을 준다고 생각해요.
|
|
101
|
+
> — @malibinYun on `src/test/kotlin/lotto/domain/LottoTest.kt`
|
|
102
|
+
|
|
103
|
+
> 너무 어려운 내용일 수도 있으니, *많은 변형을 하지 않으셔도 좋습니다* 🙂
|
|
104
|
+
> — @malibinYun
|
|
105
|
+
|
|
106
|
+
## 얻은 교훈
|
|
107
|
+
|
|
108
|
+
- **`!!`은 *Kotlin null safety 무시*** — *마지막 수단*.
|
|
109
|
+
- **재활용 가능 객체 *매번 new X*** — *상태 없는 협력자*는 *한 번 만 생성 + 재사용*.
|
|
110
|
+
- **결과 생성 *책임 위치*** = *결과 객체*에.
|
|
111
|
+
- **`delegation` *전체 인터페이스 노출* vs *일급 컬렉션 선택 노출***.
|
|
112
|
+
- **`List(n) { gen() }`** — 모든 PR 공통.
|
|
113
|
+
- **`Count` *이름에 비해 많은 의존*** = 책임 모호.
|
|
114
|
+
- **에러 메시지 *정확*** — *로또 숫자 ≠ 당첨 번호*. 어휘 정합.
|
|
115
|
+
- **`ParameterizedTest` *경계값/시나리오 분리* + `MethodSource` *복잡 객체*** + **given 단계 분리** — 테스트 가독성 3박자.
|
|
116
|
+
- **`asSequence`** — *지연 평가*. *대량 컬렉션 변환 체이닝* 시 메모리 효율.
|
|
117
|
+
- **`fun interface` 람다** — *SAM*.
|
|
118
|
+
- **`given/when/then` *짧은 테스트도*** — *읽기 가독성*.
|
|
119
|
+
- **`assertThat(Collection).hasSize()`** = assertj idiom.
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# PR #2 — [코건] 1단계 로또
|
|
2
|
+
|
|
3
|
+
- **Reviewee:** [@DYGames](https://github.com/DYGames)
|
|
4
|
+
- **PR:** https://github.com/woowacourse/kotlin-lotto/pull/2
|
|
5
|
+
- **단계:** 1단계 (초창기 PR)
|
|
6
|
+
- **리뷰어:** @malibinYun
|
|
7
|
+
- **라인 코멘트:** 57
|
|
8
|
+
|
|
9
|
+
## 잘한 점 (설계 관점)
|
|
10
|
+
|
|
11
|
+
- **`Lotto`, `Lottos`, `Bonus`, `WinNumber`, `LottoRankDeterminer` 분리**.
|
|
12
|
+
- **`require` 활용**.
|
|
13
|
+
|
|
14
|
+
## 못한 점 (설계 관점)
|
|
15
|
+
|
|
16
|
+
### 1. `World` Controller — god-controller
|
|
17
|
+
|
|
18
|
+
```kotlin
|
|
19
|
+
class World {
|
|
20
|
+
fun run() {
|
|
21
|
+
// 입력, 통계 계산, 출력 모두 World 안에
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
> 로또들을 가지고 당첨 티켓과 비교해 통계를 만드는 이 행위는 도메인 로직 입니다 :) Controller의 역할을 하는 World 객체의 책임이 정말 맞을까요?
|
|
27
|
+
|
|
28
|
+
→ `World`는 너무 광범위한 이름 + 도메인 로직까지 떠안음.
|
|
29
|
+
|
|
30
|
+
### 2. `WinNumber` vs `Lotto` 불필요한 분리
|
|
31
|
+
|
|
32
|
+
```kotlin
|
|
33
|
+
class WinNumber(val numbers: List<Int>) {. }
|
|
34
|
+
class Lotto(val numbers: List<Int>) {. }
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
> WinNumber와 Lotto의 역할에는 객체로 분리할 만큼의 큰 차이점이 있을까요?
|
|
38
|
+
|
|
39
|
+
→ 같은 데이터 + 같은 검증이면 분리 정당화 어려움. `WinningLotto(lotto, bonus)` 같은 *조합*이 자연스러움.
|
|
40
|
+
|
|
41
|
+
### 3. `LottoRankDeterminer` — feature-envy
|
|
42
|
+
|
|
43
|
+
```kotlin
|
|
44
|
+
class LottoRankDeterminer(.) {
|
|
45
|
+
fun determine(lotto: Lotto, winning: WinNumber): Rank {
|
|
46
|
+
val count = lotto.numbers.filter { it in winning.numbers }.size // ⚠ 데이터 꺼내 비교
|
|
47
|
+
return Rank.of(count)
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
> 로또 끼리 비교해서 몇 개가 맞았는지 알아보는 역할은 이 객체의 책임이 맞을까요? 로또에게 메시지를 던지는 방법을 생각해보아요
|
|
53
|
+
>
|
|
54
|
+
> Rank를 찾는 행위는 Rank에게 위임해보는 것은 어떨까요?
|
|
55
|
+
|
|
56
|
+
### 4. `RandomLottoGenerator` 매번 새 List 생성
|
|
57
|
+
|
|
58
|
+
```kotlin
|
|
59
|
+
fun generate(): Lotto {
|
|
60
|
+
val pool = (1..45).toList().shuffled() // ⚠ 매번 45개 List 새로 생성
|
|
61
|
+
return Lotto(pool.take(6))
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
> generate()를 호출할 때마다 45개 숫자를 담은 List 객체가 새로 생성되겠네요. 한 번 만 생성하고 재활용하는 방법에 대해 고민해보아요
|
|
66
|
+
|
|
67
|
+
### 5. 랜덤 테스트가 size만 검증
|
|
68
|
+
|
|
69
|
+
```kotlin
|
|
70
|
+
@Test fun `로또 6개 생성`() {
|
|
71
|
+
assertThat(generator.generate().size).isEqualTo(6) // ⚠ 1-45 범위, 중복 미확인
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
> 랜덤 요소에 대한 테스트에서 size만을 비교하는 것은 제어된 테스트를 했다는 의미를 가지기엔 어렵습니다.
|
|
76
|
+
|
|
77
|
+
## 얻은 교훈
|
|
78
|
+
|
|
79
|
+
- **Controller 이름 = 도메인 어휘**. `World`는 god-naming 패턴 — 무엇이든 들어갈 수 있음.
|
|
80
|
+
- **두 객체의 분리 정당화 = 책임/데이터의 다름**. 같으면 합치거나 *조합 객체*로.
|
|
81
|
+
- **Tell-Don't-Ask** — Determiner가 외부 객체 정보로 비교 = feature-envy.
|
|
82
|
+
- **불변 컬렉션 재활용** — `(1..45).toList()`를 *상수*로 한 번만 생성. flyweight 패턴.
|
|
83
|
+
- **랜덤 테스트 = 결정적 fake 주입** — size만 검증 ≠ 제어된 테스트.
|