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,162 @@
|
|
|
1
|
+
# PR #98 — [로또 2단계] 해나
|
|
2
|
+
|
|
3
|
+
- **Reviewee:** [@hxeyexn](https://github.com/hxeyexn)
|
|
4
|
+
- **PR:** https://github.com/woowacourse/kotlin-lotto/pull/98
|
|
5
|
+
- **단계:** 2단계 (수동 로또 추가)
|
|
6
|
+
- **리뷰어:** @KwonDae (제이든)
|
|
7
|
+
- **라인 코멘트:** 19
|
|
8
|
+
|
|
9
|
+
## 잘한 점 (설계 관점)
|
|
10
|
+
|
|
11
|
+
- **`PurchaseInformation` data class로 응집** — Amount + ManualLotteryCount 묶기.
|
|
12
|
+
- **`LotteryMachine`이 수동/자동 발급 + Ticket 반환** — 객체에 *주체적 역할* 부여.
|
|
13
|
+
- **`retryUntilSuccess` 재시도 흐름**.
|
|
14
|
+
- **1단계 리뷰 적극 반영**.
|
|
15
|
+
|
|
16
|
+
## 못한 점 (설계 관점)
|
|
17
|
+
|
|
18
|
+
### 1. Controller가 `List<List<String>>` 정제
|
|
19
|
+
|
|
20
|
+
```kotlin
|
|
21
|
+
private fun splitManualLotteries(input: List<String>): List<List<String>> {
|
|
22
|
+
val splitManualLotteries = InputView.splitManualLotteries(input)
|
|
23
|
+
val manualLotteries = mutableListOf<List<String>>()
|
|
24
|
+
splitManualLotteries.forEach { manualLotteries.add(it) }
|
|
25
|
+
return manualLotteries
|
|
26
|
+
}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
리뷰어: "InputView로부터 `List<Lottery>`를 전달받는 건 어떨까요? Controller에서 *데이터를 정제하는 책임*이 있어야 할까요?" 학생 답: "현재 `List<Lottery>`를 직접 전달받지 않은 이유는 *콘솔 이외의 다른 환경*에서 동일한 데이터를 다양한 형태로 활용." 리뷰어 답: "동료 개발자가 유지보수를 맡았을 때, `List<List<String>>`을 보고 *어떤 의미를 갖는 데이터*인지 쉽게 알 수 있을까요? 또한, 이중 List로 되어 있기에 *보일러 플레이트 코드*도 발생. *원시값을 포장하여 모델로서의 역할을 부여*해준 후 Controller에게 넘긴다면 그것으로 역할은 충분."
|
|
30
|
+
|
|
31
|
+
### 2. `ManualLotteryCount` 단독 객체 vs *구매 정보*로 응집
|
|
32
|
+
|
|
33
|
+
```kotlin
|
|
34
|
+
class ManualLotteryCount(val count: Int) {. }
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
리뷰어: "ManualLotteryCount 역할을 좀 더 의미 있게 활용해 볼까요? 현재 프로젝트 내에서 ManualLotteryCount 클래스는 *구매 정보에 가까운 성격*을 띄우고 있네요. 그렇다면 *구매 정보에 관련된 값들을 하나의 클래스*에 모아 책임을 갖도록." 학생 수정: `PurchaseInformation` data class 도입하여 Amount + ManualLotteryCount 응집.
|
|
38
|
+
|
|
39
|
+
### 3. Controller가 *수동/자동 발급 + 티켓 조립* 분담
|
|
40
|
+
|
|
41
|
+
```kotlin
|
|
42
|
+
val manualLotteries = issueManualLotteries(splitManualLotteries)
|
|
43
|
+
val autoLotteries = issueAutoLotteries(amount, manualLotteryCount)
|
|
44
|
+
val ticket = issueTicket(manualLotteries, autoLotteries, amount)
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
학생 자가 의문: "TicketGenerationStrategy가 Ticket을 반환하는 것이 아니라 Lottery를 반환해 *티켓의 역할이 모호*해졌고, *티켓 전략과 티켓의 역할*에 대한 의문이 들었습니다. 굳이 전략이 필요한가? 라는 생각도 들어서…" 리뷰어: "Controller에서 개별 로또마다 수동, 자동을 뽑아내서 티켓을 발급받도록 하는 과정이 *필요할까요*? Controller -> LottoMachine에게 *필요한 정보(수동 로또, 구매금액.)를 전달*해서 LottoMachine이 *알아서 수동, 자동 로또를 발급*하고 Ticket을 반환받도록. *LottoMachine에게 좀 더 주체적인 역할을 부여*." 학생 수정 완료.
|
|
48
|
+
|
|
49
|
+
### 4. `start()` 메서드의 가독성
|
|
50
|
+
|
|
51
|
+
```kotlin
|
|
52
|
+
fun start() {
|
|
53
|
+
val amount = retryUntilSuccess { readAmount() }
|
|
54
|
+
val manualLotteryCount = retryUntilSuccess { readManualLotteryCount(amount) }
|
|
55
|
+
val manualLotteriesInput = readManualLotteries(manualLotteryCount)
|
|
56
|
+
val splitManualLotteries = splitManualLotteries(manualLotteriesInput)
|
|
57
|
+
val manualLotteries = issueManualLotteries(splitManualLotteries)
|
|
58
|
+
val autoLotteries = issueAutoLotteries(amount, manualLotteryCount)
|
|
59
|
+
val ticket = issueTicket(manualLotteries, autoLotteries, amount)
|
|
60
|
+
printTicketInfo(ticket)
|
|
61
|
+
.
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
리뷰어: "동료 개발자가 보게 되었을 경우 빠른 시간 내 이해하기 어떨까요? *파편화 되어 있는 함수들을 순서대로 보았을 때 이해하기 쉽도록* 해볼 수 있을 것 같아요. 1. 사용자로부터 입력 받는 함수 2. 로또 생성 함수 3. 당첨 로또 입력 받는 함수 4. 당첨금 계산. 식으로 Controller 내부에서도 함수들을 정리해 볼 수 있겠네요." 학생 정리.
|
|
66
|
+
|
|
67
|
+
### 5. 1000원 미만 = 종료, 잔돈 안내 부재 — 키오스크 비유
|
|
68
|
+
|
|
69
|
+
리뷰어: "현재는 구입금액이 1000원 미만이면 *바로 Exception을 발생시켜 종료*시키고 있습니다. 식당의 키오스크를 생각해 보면, 기본금액 5000원 이상인 식당에서 우리가 *현금을 1000원을 넣는다고 프로그램이 종료*될까요? *5000원 이상 투입* 안내문구를 띄운다든가, 무엇이 잘못됐는지 알려줘 가이드를 할 수 있겠죠. 미션에서 요구하는 *논리적인 오류*는 사용자가 경험하는 *모든 과정*에 있어서 Exception을 던져야 하는 상황인지, 혹은 어떠한 오류가 발생했을 때 적절하게 *문제를 해결하도록* 할 것인지 기대." — 키오스크 비유로 *재시도 vs 종료* 명확화.
|
|
70
|
+
|
|
71
|
+
### 6. Controller에서 Amount null 처리 vs InputView에서 null 반환
|
|
72
|
+
|
|
73
|
+
```kotlin
|
|
74
|
+
// Controller 내에서 처리
|
|
75
|
+
private fun readAmount(): Amount {
|
|
76
|
+
return runCatching {
|
|
77
|
+
Amount.fromInput(inputView.readAmount()) ?: readAmount()
|
|
78
|
+
}.getOrElse { throwable ->
|
|
79
|
+
outputView.printError(throwable.message ?: "잘못된 입력")
|
|
80
|
+
readAmount()
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
리뷰어: "Controller에서 try-catch or runCatching 같은 코드들이 필요 없게 할 수 있을까요? *InputView로부터 검증된 Amount를 Controller가 전달받는다면 어떨까요*? `fun readAmount(): Amount? { runCatching { Amount(readln().toInt()) }.getOrNull() }`. 이렇게 *Amount?*를 nullable하게 활용할 수 있겠네요." — null 반환으로 *Controller가 분기*.
|
|
86
|
+
|
|
87
|
+
### 7. `ManualLotteriesGenerationStrategy` — *단순 매핑*에 Strategy?
|
|
88
|
+
|
|
89
|
+
```kotlin
|
|
90
|
+
class ManualLotteriesGenerationStrategy(.) : LotteriesGenerationStrategy {
|
|
91
|
+
override fun generate(): List<Lottery> = manualLotteries.map { Lottery.fromInput(it) }
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
리뷰어: "`ManualLotteriesGenerationStrategy`의 역할에 대해서 살펴보면 현재 *단순 Lottery로 mapping*해 주는 것 외에는 비즈니스 로직이 존재하지 않습니다. `RandomLotteriesGenerationStrategy`의 경우엔 *랜덤이라는 비즈니스 로직*이 존재하지만, List<List<Int>> -> List<Lottery> 과정에서 과연 *ManualLotteriesGenerationStrategy가 정말 필요한가*에 대해 생각해 보아도 좋을 것 같아요. 어차피 검증 로직은 Lottery에 존재." 학생: "전략 패턴을 사용했으니 *꼭 이걸 수동 로또에도 이용해야겠다는 생각에 갇혀있었던 것* 같습니다. 개발도 *상황에 따라 유연하게 사고*하는 게 중요하다."
|
|
96
|
+
|
|
97
|
+
### 8. *재귀 InputView*가 *Controller 제어권* 박탈
|
|
98
|
+
|
|
99
|
+
```kotlin
|
|
100
|
+
private fun readManualLottery(): List<Int> {
|
|
101
|
+
val lottery = splitManualLottery(readln()).mapNotNull { it.toIntOrNull() }
|
|
102
|
+
if (lottery.size == LOTTERY_COUNT) return lottery
|
|
103
|
+
println(EXCEPTION_IS_NOT_NUMBER)
|
|
104
|
+
return readManualLottery()
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
리뷰어: "이것은 *예외가 발생했을 때의 처리 제어권*을 어디로 위임할 거냐로 볼 수 있습니다. 예외 상황이 발생했을 때 이곳처럼 *다시 해당 함수를 호출하는 상황*에서는 *Controller가 개입을 할 수 없습니다*. 1차적으로 InputView에서 숫자로 이루어졌는지 확인을 한 후, LotteryNumber로 wrapping 하는 과정에서 *Controller에게 null을 반환*하여 Controller에서 *null에 대한 처리를 하게끔 제어권을 넘겨주는* 건 어떨까요?" + "만약 요구사항이 변경되어 예외 상황에 대한 추가 로직이 필요할 때 현재로서는 InputView에 코드를 추가하여 *view에서 비즈니스 로직을 처리*하게 될 겁니다. 결국 *MVC 패턴 구조의 장점이 사라지게* 되겠죠."
|
|
109
|
+
|
|
110
|
+
### 9. `ManualLotteryCount.validatePurchaseBound`의 require가 종료 유발
|
|
111
|
+
|
|
112
|
+
```kotlin
|
|
113
|
+
private fun readManualLotteryCount(amount: Amount): ManualLotteryCount {
|
|
114
|
+
while (true) {
|
|
115
|
+
val manualLotteryCount = ManualLotteryCount.fromInput(.)
|
|
116
|
+
if (manualLotteryCount != null) return manualLotteryCount
|
|
117
|
+
OutputView.printError(EXCEPTION_IS_NOT_NUMBER)
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
리뷰어: "ManualLotteryCount 내부 validatePurchaseBound의 require로 인해 Exception이 발생하면 어떻게 될까요? 위의 readAmount()와 같이 *빈번한 Exception 발생*은 프로그램 실행에 *좋은 영향을 주지 않습니다*."
|
|
123
|
+
|
|
124
|
+
### 10. 테스트 Fixture 인라인
|
|
125
|
+
|
|
126
|
+
리뷰어: "참고로 테스트에 *Test Fixture*라는 개념이 있습니다. 이는 여러 테스트에서 같은 Data를 사용할 때, *코드 중복을 피하면서 가독성을 높이는* 방법."
|
|
127
|
+
|
|
128
|
+
## 리뷰어 의견 요지
|
|
129
|
+
|
|
130
|
+
- **이중 컬렉션 `List<List<X>>` 회피** — *도메인 객체*로 감싸기.
|
|
131
|
+
- **관련 값 *응집 클래스*** — `Amount` + `ManualLotteryCount`처럼 *함께 쓰이는 값*은 *PurchaseInformation*.
|
|
132
|
+
- **Machine에 *주체적 책임*** — Controller는 *조립*, Machine이 *발행+티켓 반환*.
|
|
133
|
+
- **키오스크 비유** — *논리 오류*는 *바로 종료*가 아니라 *재시도 안내*.
|
|
134
|
+
- **InputView가 null 반환 → Controller가 분기** — *제어권*을 Controller로.
|
|
135
|
+
- **Strategy는 *비즈니스 로직이 있을 때*만** — 단순 매핑은 *추상화 비용*만.
|
|
136
|
+
- **재귀 InputView = MVC 장점 소실** — *view에서 비즈니스 분기*가 누적.
|
|
137
|
+
- **Test Fixture** — 중복 데이터 *명시적 변수*로.
|
|
138
|
+
|
|
139
|
+
- **대표 인용:**
|
|
140
|
+
> 동료 개발자가 유지보수를 맡았을 때, `List<List<String>>`을 보고 어떤 의미를 갖는 데이터인지 쉽게 알 수 있을까요?
|
|
141
|
+
> — @KwonDae on `src/main/kotlin/lotto/view/InputView.kt`
|
|
142
|
+
|
|
143
|
+
> 식당의 키오스크를 생각해 보면, 기본금액 5000원 이상인 식당에서 우리가 현금을 1000원을 넣는다고 *프로그램이 종료*될까요? 5000원 이상 투입 안내문구를 띄운다든가, 무엇이 잘못됐는지 알려줘 가이드.
|
|
144
|
+
> — @KwonDae on `src/main/kotlin/lotto/controller/LotteryController.kt`
|
|
145
|
+
|
|
146
|
+
> 다시 해당 함수를 호출하는 상황에서는 Controller가 개입을 할 수 없습니다. *Controller에게 null을 반환*하여 Controller에서 null에 대한 처리를 하게끔 *제어권을 넘겨주는* 건 어떨까요?
|
|
147
|
+
> — @KwonDae on `src/main/kotlin/lotto/view/InputView.kt`
|
|
148
|
+
|
|
149
|
+
> `ManualLotteriesGenerationStrategy`의 역할은 *단순 Lottery로 mapping*해 주는 것 외에는 비즈니스 로직이 존재하지 않습니다. 과연 *정말 필요한가*에 대해 생각해 보아도.
|
|
150
|
+
> — @KwonDae on `src/main/kotlin/lotto/view/InputView.kt`
|
|
151
|
+
|
|
152
|
+
## 얻은 교훈
|
|
153
|
+
|
|
154
|
+
- **이중 컬렉션은 의도 모호** — `List<List<X>>`보다 *도메인 객체*로 감싸기.
|
|
155
|
+
- **관련 값 *응집 클래스*** — `Amount` + `ManualLotteryCount`처럼 *함께 쓰이는 값*은 *PurchaseInformation*.
|
|
156
|
+
- **Machine에 *주체적 책임*** — Controller는 *조립*, Machine이 *발행+티켓 반환*까지.
|
|
157
|
+
- **키오스크 비유** — *논리 오류*는 *바로 종료*가 아니라 *재시도 안내*.
|
|
158
|
+
- **InputView가 null 반환** — Controller에 *분기 제어권*. 재귀 호출은 *Controller 제어권 박탈* + *MVC 장점 소실*.
|
|
159
|
+
- **Strategy는 *비즈니스 로직이 있을 때*** — *단순 매핑*에 Strategy 도입은 *추상화 비용*만. 패턴에 *갇히지 말 것*.
|
|
160
|
+
- **Test Fixture** — 중복 데이터를 *명시적 변수*로 분리 + *재사용*.
|
|
161
|
+
- **`runCatching.getOrNull()`** — *예외를 null로 흡수*하는 표준 패턴.
|
|
162
|
+
- **Kotlin이 *Checked Exception*을 제공하지 않는 이유** — 예외 처리에 *정답은 없음*, *Result/null/예외*를 *상황에 맞게*.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# PR #17 — [둘리] 1단계 로또
|
|
2
|
+
|
|
3
|
+
- **Reviewee:** [@hyemdooly](https://github.com/hyemdooly)
|
|
4
|
+
- **PR:** https://github.com/woowacourse/kotlin-lotto/pull/17
|
|
5
|
+
- **단계:** 1단계
|
|
6
|
+
- **리뷰어:** @vagabond95
|
|
7
|
+
- **라인 코멘트:** 10
|
|
8
|
+
|
|
9
|
+
## 핵심 지적
|
|
10
|
+
|
|
11
|
+
- **Rank `values()` 활용 간결화**.
|
|
12
|
+
- **LottoResult 함수 분리 + 변수 단계 가독성**.
|
|
13
|
+
- **LottoNumber 재사용 (flyweight)**.
|
|
14
|
+
- **`Amount` 원시값 포장 + 검증 위임**.
|
|
15
|
+
|
|
16
|
+
## 얻은 교훈
|
|
17
|
+
|
|
18
|
+
- **`values().find/forEach`** — enum 전체 순회 표준.
|
|
19
|
+
- **LottoNumber flyweight** — 1억 티켓도 45개 인스턴스만.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# PR #28 — [둘리] 2단계 로또
|
|
2
|
+
|
|
3
|
+
- **Reviewee:** [@hyemdooly](https://github.com/hyemdooly)
|
|
4
|
+
- **PR:** https://github.com/woowacourse/kotlin-lotto/pull/28
|
|
5
|
+
- **단계:** 2단계
|
|
6
|
+
- **리뷰어:** @vagabond95
|
|
7
|
+
- **라인 코멘트:** 10
|
|
8
|
+
|
|
9
|
+
## 잘한 점
|
|
10
|
+
|
|
11
|
+
- **`Count` 값 포장 + operator overloading** — 칭찬.
|
|
12
|
+
|
|
13
|
+
## 핵심 지적
|
|
14
|
+
|
|
15
|
+
- **operator overloading의 반환 타입 = 감싸는 원시값 X**. 같은 wrapper 타입으로.
|
|
16
|
+
- **LottoStore를 수동에도 활용** — 자동/수동 통합.
|
|
17
|
+
|
|
18
|
+
> Lotto 를 생성하는 방식이 구매 방식에 따라 파편화되기 시작하면, 점점 구조를 파악하는데 어려움이 생길 수 있.
|
|
19
|
+
|
|
20
|
+
## 얻은 교훈
|
|
21
|
+
|
|
22
|
+
- **operator overload 반환 = 같은 wrapper 타입**. `Money + Money = Money`.
|
|
23
|
+
- **자동/수동 통합 = LottoStore 인터페이스**. 파편화 회피.
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
# PR #15 — [뽀또] 1단계 로또 제출합니다
|
|
2
|
+
|
|
3
|
+
- **Reviewee:** [@hyunji1203](https://github.com/hyunji1203)
|
|
4
|
+
- **PR:** https://github.com/woowacourse/kotlin-lotto/pull/15
|
|
5
|
+
- **단계:** 1단계
|
|
6
|
+
- **리뷰어:** @laco-dev
|
|
7
|
+
- **라인 코멘트:** 85
|
|
8
|
+
|
|
9
|
+
## 잘한 점 (설계 관점)
|
|
10
|
+
|
|
11
|
+
- **`Money`, `Lotto`, `Lottos`, `Rank`, `WinningResult`, `LottoGenerator` 도메인 분리** — 책임 단위로 클래스.
|
|
12
|
+
- **`LottoGenerator` 인터페이스** — `RandomLottoGenerator` 구현체 분리.
|
|
13
|
+
- **`Rank` enum + 등수별 출력 override** (개선 필요).
|
|
14
|
+
- **`require()` 활용**.
|
|
15
|
+
|
|
16
|
+
## 못한 점 (설계 관점)
|
|
17
|
+
|
|
18
|
+
### 1. Controller의 lateinit + Coordinator 책임 모호
|
|
19
|
+
|
|
20
|
+
```kotlin
|
|
21
|
+
class LottoGame {
|
|
22
|
+
private val input by lazy { InputView() }
|
|
23
|
+
private val output by lazy { OutputView() }
|
|
24
|
+
lateinit var money: Money
|
|
25
|
+
lateinit var lottos: Lottos
|
|
26
|
+
lateinit var winningResult: WinningResult
|
|
27
|
+
|
|
28
|
+
fun run() {
|
|
29
|
+
initGame()
|
|
30
|
+
startGame()
|
|
31
|
+
endGame()
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
`money`, `lottos`, `winningResult`가 Controller 멤버 변수로 보유 → 함수 결과 예측 어려움.
|
|
37
|
+
`initGame/startGame/endGame`이 public → 외부에서 잘못된 순서로 호출 가능.
|
|
38
|
+
|
|
39
|
+
### 2. `BonusNumber`가 Lotto와 별개 클래스 (도메인 중복)
|
|
40
|
+
|
|
41
|
+
```kotlin
|
|
42
|
+
class Lotto(val numbers: List<Int>) {
|
|
43
|
+
init {
|
|
44
|
+
require(numbers.size == 6) { INPUT_LOTTO_SIZE_ERROR_MESSAGE }
|
|
45
|
+
require(numbers.toSet().size == 6) { INPUT_LOTTO_DUPLICATE_ERROR_MESSAGE }
|
|
46
|
+
require(numbers.filter { number -> number in 1..45 }.size == 6) { INPUT_LOTTO_RANGE_ERROR_MESSAGE }
|
|
47
|
+
}
|
|
48
|
+
fun countMatchNumber(lotto: Lotto): Int {. }
|
|
49
|
+
fun hasBonusNumber(bonusNumber: BonusNumber): Boolean {. }
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
`1..45` 범위 검증이 `Lotto` 내부 + `BonusNumber` 내부 양쪽에. → **`LottoNumber` 값 객체로 추출하면 중복 제거 + 도메인 개념 1급화**.
|
|
54
|
+
|
|
55
|
+
### 3. `Lotto`가 내부 `numbers`를 외부에 그대로 노출
|
|
56
|
+
|
|
57
|
+
```kotlin
|
|
58
|
+
class Lotto(val numbers: List<Int>) {
|
|
59
|
+
fun countMatchNumber(lotto: Lotto): Int {
|
|
60
|
+
return numbers.filter { lotto.numbers.contains(it) }.size // ⚠ 외부에서도 numbers 직접 접근
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
호출처에서 `lotto.numbers.contains(.)` 같은 로직이 가능 → 캡슐화 약함.
|
|
66
|
+
|
|
67
|
+
### 4. OutputView가 도메인 계산까지
|
|
68
|
+
|
|
69
|
+
```kotlin
|
|
70
|
+
class OutputView {
|
|
71
|
+
fun outputLottoSizeMessage(money: Money) {
|
|
72
|
+
println((money.price / LOTTO_PRICE).toString() + OUTPUT_LOTTO_SIZE_MESSAGE)
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
> "구매 가능한 로또의 갯수를 OutputView가 너무 똑똑하게 알고 있지는 않을까요? 만약, 로또 구매 갯수를 계산하는 비즈니스 로직이 수정된다면, UI 코드가 바뀌어야 하겠죠?"
|
|
78
|
+
|
|
79
|
+
→ 계산은 도메인(`Money.numberOfLottos()` 같은), 출력은 UI.
|
|
80
|
+
|
|
81
|
+
### 5. `Rank` enum에 UI 표현 override
|
|
82
|
+
|
|
83
|
+
```kotlin
|
|
84
|
+
enum class Rank(val countOfMatch: Int, val winningMoney: Int) {
|
|
85
|
+
FIRST(6, 2_000_000_000),
|
|
86
|
+
SECOND(5, 30_000_000) {
|
|
87
|
+
override fun toString(): String = RANK_BONUS_MESSAGE.format(countOfMatch, winningMoney)
|
|
88
|
+
},
|
|
89
|
+
.
|
|
90
|
+
override fun toString(): String = RANK_MESSAGE.format(countOfMatch, winningMoney)
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
> "Rank에 대한 출력 값은 UI의 관심사입니다. 도메인 모델에서 UI 로직을 제거하고."
|
|
95
|
+
|
|
96
|
+
### 6. `null` 대신 `MISS` enum 활용 미흡
|
|
97
|
+
|
|
98
|
+
```kotlin
|
|
99
|
+
fun findRank(.): Rank? {. } // ⚠ MISS가 있는데 null 반환
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
> "MISS 라는 타입이 있으니 논리적으로 null을 반환하는 것 보다 MISS를 반환하는게 좋지 않을까요?"
|
|
103
|
+
|
|
104
|
+
### 7. 테스트가 다른 도메인을 끌어들임
|
|
105
|
+
|
|
106
|
+
```kotlin
|
|
107
|
+
class LottoTest {
|
|
108
|
+
@Test
|
|
109
|
+
fun `랜덤.`() {
|
|
110
|
+
val lottos = RandomLottoGenerator().generateLottos(.) // ⚠ LottoTest인데 Generator 등장
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
> "이 테스트는 LottoTest이기 때문에 LottoGenerator를 사용하지 않고 작성되어야 합니다."
|
|
116
|
+
|
|
117
|
+
### 8. 테스트 함수명 모호
|
|
118
|
+
|
|
119
|
+
```kotlin
|
|
120
|
+
fun `입력된 금액이 null 일 때`() {. }
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
→ null일 때 *무엇을* 검증? 예외 발생? 기본값 반환? 본문을 봐야 앎.
|
|
124
|
+
|
|
125
|
+
### 9. 커밋 단위 — 구현 없이 테스트만 추가
|
|
126
|
+
|
|
127
|
+
```
|
|
128
|
+
test(MoneyTest): 입력된 금액 확인하는 테스트 추가
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
> "하나의 기능 (커밋)은 반드시 테스트 코드와 구현 코드가 같이 존재해야 합니다. 지금 커밋에서는 Money라는 객체가 없기 때문에 오류가 발생합니다."
|
|
132
|
+
|
|
133
|
+
## 리뷰어 의견 요지
|
|
134
|
+
|
|
135
|
+
리뷰어 @laco-dev의 핵심 가르침 (racingcar에서도 동일 학생을 본 리뷰어):
|
|
136
|
+
|
|
137
|
+
1. **"로또 번호" 도메인 추출** — `Lotto`와 `BonusNumber`가 같은 범위(1-45) 검증을 중복하면 그건 *공통 개념*이 누락된 신호. `LottoNumber` 값 객체로.
|
|
138
|
+
|
|
139
|
+
2. **컬렉션 추상화 = 일급 컬렉션** — Lotto가 `List<LottoNumber>`를 그대로 노출하지 말고, "로또 번호들" 객체를 만들어 (1) 6개 보장, (2) 일치 개수 계산, (3) 포함 여부 등 메서드만 노출.
|
|
140
|
+
|
|
141
|
+
3. **UI는 똑똑하지 않게** — 도메인 계산이 OutputView에 들어가면 UI 수정 시 도메인 영향. 도메인이 계산해서 결과만 UI로.
|
|
142
|
+
|
|
143
|
+
4. **`null` 대신 enum 케이스** — `MISS`가 있으면 그걸 반환. `null` 처리 강제는 호출자의 부담.
|
|
144
|
+
|
|
145
|
+
5. **테스트는 한 클래스에 집중** — `LottoTest`에서 `LottoGenerator`를 쓰면 테스트 범위 흐림. SUT(Subject Under Test) 명확히.
|
|
146
|
+
|
|
147
|
+
- **대표 인용:**
|
|
148
|
+
> 로또에서 사용하는 번호가 BonusNumber와 중복해서 로직을 사용하고 있습니다. "로또 번호" 라는 역할을 만들어서 개선 해보세요.
|
|
149
|
+
>
|
|
150
|
+
> — @laco-dev on `src/main/kotlin/domain/Lotto.kt`
|
|
151
|
+
|
|
152
|
+
> Lotto를 사용하는 곳에서는 numbers 라는 타입이 몇개인지 알지 못하고, 위 작성된 코드처럼 로직이 외부로 노출되는 문제로 이어질 수 있습니다.
|
|
153
|
+
>
|
|
154
|
+
> — @laco-dev on `src/main/kotlin/domain/Lotto.kt`
|
|
155
|
+
|
|
156
|
+
> 구매 가능한 로또의 갯수를 OutputView가 너무 똑똑하게 알고 있지는 않을까요? 만약, 로또 구매 갯수를 계산하는 비즈니스 로직이 수정된다면, UI 코드가 바뀌어야 하겠죠? UI에서는 최대한 똑똑하지 않게 만드는 것도 좋습니다.
|
|
157
|
+
>
|
|
158
|
+
> — @laco-dev on `src/main/kotlin/view/OutputView.kt`
|
|
159
|
+
|
|
160
|
+
> MISS 라는 타입이 있으니 논리적으로 null을 반환하는 것 보다 MISS를 반환하는게 좋지 않을까요?
|
|
161
|
+
>
|
|
162
|
+
> — @laco-dev on `src/main/kotlin/domain/Rank.kt`
|
|
163
|
+
|
|
164
|
+
## 얻은 교훈
|
|
165
|
+
|
|
166
|
+
- **중복된 검증 = 누락된 도메인 개념의 신호**. Lotto의 number(1-45) + BonusNumber(1-45) → 공통 개념 `LottoNumber`로 추출. 검증이 한 곳에.
|
|
167
|
+
- **일급 컬렉션의 가치 = "어떻게 다루는지를 캡슐화"**. `List<Int>` 그대로 노출하면 호출처가 `.contains()`, `.filter()` 직접 사용. 일급 컬렉션 (`Numbers`)이 메서드만 노출하면 외부는 도메인 어휘로만 대화.
|
|
168
|
+
- **UI는 똑똑하지 않게** = OutputView가 도메인 계산하면 도메인 변경이 UI까지 번짐.
|
|
169
|
+
- **enum의 모든 상태를 활용 = `null` 회피**. `MISS`/`NONE` 케이스가 있으면 그걸 반환. `Rank?` 같은 nullable로 호출자 부담 늘리지 말 것.
|
|
170
|
+
- **테스트의 SUT 명확히**. `LottoTest`는 `Lotto`만 검증. 다른 클래스 사용 = 테스트 범위 흐려짐.
|
|
171
|
+
- **커밋 단위 = "테스트 + 구현 함께"**. 컴파일 안 되는 커밋은 그 시점의 상태를 다시 가져갈 수 없음.
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
# PR #48 — [뽀또] 2단계 로또
|
|
2
|
+
|
|
3
|
+
- **Reviewee:** [@hyunji1203](https://github.com/hyunji1203)
|
|
4
|
+
- **PR:** https://github.com/woowacourse/kotlin-lotto/pull/48
|
|
5
|
+
- **단계:** 2단계 (수동 로또)
|
|
6
|
+
- **리뷰어:** @laco-dev (라코)
|
|
7
|
+
- **라인 코멘트:** 34 (리뷰어 19 + 학생 15)
|
|
8
|
+
|
|
9
|
+
## 잘한 점 (설계 관점)
|
|
10
|
+
|
|
11
|
+
- **`Lottos` 위임 활용** — 리뷰어 칭찬: "*위임을 이용해 Lottos가 리스트 타입이 되도록 한 점은 잘 해 주셨*습니다. 👍🏻".
|
|
12
|
+
- **`Rank` 테스트 명세성** — 칭찬: "*Rank가 어떤 기능을 하는지, 어떤 등수가 있는지 테스트 코드만 보고 바로 이해할 수 있게 되었어요*. 👍🏻".
|
|
13
|
+
- **`LottoGenerator` 인터페이스** — 시도.
|
|
14
|
+
- **`LottoMaker` 도입** — 후속 *간소화*.
|
|
15
|
+
|
|
16
|
+
## 못한 점 (설계 관점)
|
|
17
|
+
|
|
18
|
+
### 1. `LottoMaker` *협력 없는 단독 생성* + RandomLottoGenerator 직접 의존
|
|
19
|
+
|
|
20
|
+
```kotlin
|
|
21
|
+
class LottoMaker {
|
|
22
|
+
fun make(): Lotto {
|
|
23
|
+
val generator = RandomLottoGenerator() // ⚠ 직접 생성
|
|
24
|
+
return.
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
리뷰어: "1. *LottoMaker는 아무런 협력이 없이, 단순히 로또를 만들고만 있*어요. 2. *도메인 로직이 다시 RandomLottoGenerator()라는 불확실성과 의존성을 가지게 되었*어요. *로또를 만든다 → 로또 제너레이터에게 로또를 요청한다 → 로또를 반환한다* 순서의 흐름이 되려면 어떻게 할 수 있을까요? *의존성을 주입하는 방법은 생성자 뿐만 아니라 대표적으로 3가지 방법*을 사용할 수 있습니다."
|
|
30
|
+
|
|
31
|
+
### 2. *수동/자동 generator 인터페이스 분리* — 추상화 목적 상실
|
|
32
|
+
|
|
33
|
+
학생 후속: "*수동 로또 제너레이터 인터페이스와 자동 로또 제너레이터 인터페이스를 따로*"
|
|
34
|
+
|
|
35
|
+
리뷰어: "*방향을 잘못 접근*하셨습니다. *수동인지 자동인지를 모르게 하기 위한 목적인데, 따로 만든다는 것 자체가 근본적으로 인터페이스로 만들 이유가 없게 되지 않을까요*?"
|
|
36
|
+
|
|
37
|
+
추가 (인터페이스 의도): "로또 제너레이터가 인터페이스로 만들어지게 되면서 *기대할 수 있는 것은 구현에 관심없이 로또 번호를 반환하는 것*을 생각할 수 있습니다. 하지만 지금은 *RandomLottoGenerator만 사용되고, 수동 로또는 InputView에서 바로 만들고 있*습니다. 이 경우, *인터페이스 활용을 못하고 있다*고 볼 수 있습니다. 로또 메이커에게 → 로또를 만들어 주세요 → *로또를 어떻게 만들어요* → 로또 번호 제너레이터에게 요청해요 → 로또를 만들어서 돌려줘요. 이러한 요구사항을 구현하면서, *랜덤 로또 번호를 만들어 줄지, 수동 로또 번호를 만들어 줄지 모르게 만드는 것이 목표*이겠습니다." — 안티.
|
|
38
|
+
|
|
39
|
+
리뷰어 후속 (정답 제시):
|
|
40
|
+
```kotlin
|
|
41
|
+
class LottoMaker {
|
|
42
|
+
// 더이상 수동으로 만들지, 자동으로 만들지 관심이 없어짐
|
|
43
|
+
fun makeLottos(count: Int, lottoGenerator: LottoGenerator): Lottos {
|
|
44
|
+
return Lottos(lottoGenerator.generate(count))
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
// 호출부
|
|
48
|
+
val manualLottos = lottoMaker.makeLottos(ManualLottoGenerator)
|
|
49
|
+
val autoLottos = lottoMaker.makeLottos(RandomLottoGenerator)
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### 3. `RandomLottoGenerator` *도메인 모델 위치* 의문
|
|
53
|
+
|
|
54
|
+
리뷰어: "저는 *랜덤 로또 제너레이터 구현체가 도메인 모델에 위치할 필요가 있을까? 생각이 들기도* 해요. 로또 게임이라는 도메인 안에서 *랜덤으로 만들어서 돌려준다가 비즈니스 로직이라고 볼 수도 있지만, 다르게 생각하면 어떻게 입력받는지 상관없이 LottoGenerator만 알면 되지 않을까*? 라고 생각을 해서요. 그렇게 본다면 예를 들어 *로또 번호를 키오스크에서 입력받을 수도 있고, 종이로도 입력받을 수도 있고 등등 다양한 방법*이 존재합니다. 즉, *도메인 외에 여러 가지 다양한 의존성을 가질 수 있다는 의미*인데요. 하지만 필요한 것은 *LottoGenerator라는 인터페이스 타입만 필요하지 구현체에는 관심이 없어야* 합니다. 그런 의미로 저는 *게임을 어떻게 풀어낼지 결정하는 위 구현체는 컨트롤러 쪽에서 결정이 되어야 하지 않을까* 합니다."
|
|
55
|
+
|
|
56
|
+
### 4. Controller 검증 *중복*
|
|
57
|
+
|
|
58
|
+
리뷰어: "*이 검증 로직은 도메인 모델에서 수행하고 있기 때문에 중복이라고 볼 수 있지 않을까요*?"
|
|
59
|
+
|
|
60
|
+
### 5. *Rank fallback null* — `MISS` 활용
|
|
61
|
+
|
|
62
|
+
```kotlin
|
|
63
|
+
fun from(.): Rank? = entries.find {. } // ⚠ null
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
리뷰어: "*일치하지 않는 Rank가 있는 경우, MISS 타입을 반환해야 하지 않을까요*??" + "*Rank의 miss 타입을 사용하기 때문에 null 타입으로 반환하지 않아도 되지 않을까요*!?" — *NullObject 패턴*: `MISS`가 *null 대체*.
|
|
67
|
+
|
|
68
|
+
### 6. *파라미터는 불변 List*
|
|
69
|
+
|
|
70
|
+
리뷰어: "*파라미터를 받을 때에는 가급적 불변 객체인 List 타입을 받도록* 합니다." — `MutableList` 외부 노출 X.
|
|
71
|
+
|
|
72
|
+
### 7. `Lottos.count` 위임 vs *명시 메서드*
|
|
73
|
+
|
|
74
|
+
리뷰어: "위임을 이용해 Lottos가 리스트 타입이 되도록 한 점은 잘 해 주셨습니다. 👍🏻 다만, *객체가 해야 할 책임과 비즈니스 로직을 외부에서 뺏어서 작성할 수 있다는 의중성은 잘 염두해 두시면* 좋겠습니다. 가령 아래와 같이 *Lottos에게 요청을 해야 할 로직도 밖에서 작성할 위험*을 가집니다.
|
|
75
|
+
```kotlin
|
|
76
|
+
val lottos: Lottos
|
|
77
|
+
val lottoMatchCount = lottos.count {. } // 이게 호출이 되니 자연스럽게 이렇게 하게 됨
|
|
78
|
+
|
|
79
|
+
val lottos: Lottos
|
|
80
|
+
val lottoMatchCount = lottos.getMatchCount() // 이게 맞음!
|
|
81
|
+
```" — *위임의 양면성*: *컬렉션 인터페이스 노출*은 *외부 조립 유혹*.
|
|
82
|
+
|
|
83
|
+
### 8. `matchLottos` *중복 함수*
|
|
84
|
+
|
|
85
|
+
리뷰어: "이미 WinningResult를 반환하는 위 matchLottos 함수가 있는데, *이 함수가 새로 만들어진 이유가 무엇*인가요??"
|
|
86
|
+
|
|
87
|
+
### 9. *INPUT_XX 네이밍 — UI 결합*
|
|
88
|
+
|
|
89
|
+
리뷰어: "*도메인 로직이기 때문에 INPUT_XX 형태로 UI 입력과 관련성이 있는 네이밍은 피하는 게 좋겠*습니다." — *도메인 어휘*는 *UI 무관*.
|
|
90
|
+
|
|
91
|
+
### 10. `getOrDefault` vs `getOrElse`
|
|
92
|
+
|
|
93
|
+
리뷰어: "*getOrDefault() 함수는 실제 값을 가져오기 먼저 호출이* 됩니다. *getOrElse {. }와 getOrDefault() 함수가 어떤 차이를 가지는지* 한번 고민해 보세요." — *eager evaluation* vs *lazy evaluation*. `getOrDefault(key, expensiveCall())`은 *항상 expensiveCall 실행*.
|
|
94
|
+
|
|
95
|
+
### 11. *라인 줄이려고 가독성 희생*
|
|
96
|
+
|
|
97
|
+
리뷰어: "*라인 수를 줄이기 위해 가독성이 많이 떨어졌*습니다. *변수를 이용해 가독성을 개선*해 보세요."
|
|
98
|
+
|
|
99
|
+
### 12. *프로퍼티 이름 대문자* — Kotlin 컨벤션
|
|
100
|
+
|
|
101
|
+
리뷰어: "*프로퍼티의 이름은 소문자로 시작*해야 합니다. https://kotlinlang.org/docs/coding-conventions.html#naming-rules"
|
|
102
|
+
|
|
103
|
+
### 13. *파라미터 이름 `a`* — 모호
|
|
104
|
+
|
|
105
|
+
리뷰어: "*'a'가 무엇일까요*..? *파라미터를 단순한 이름으로 사용하지 말아야* 합니다. *코틀린 컬렉션의 plus 함수에는 무엇으로 사용하는지 찾아*보세요." — Kotlin `plus(other:.)`.
|
|
106
|
+
|
|
107
|
+
### 14. `println()` *디버깅 잔여물*
|
|
108
|
+
|
|
109
|
+
리뷰어: "*println()은 어떤. 과정으로 추가가 되었을까요*?" — *PR 셀프 리뷰 부재*.
|
|
110
|
+
|
|
111
|
+
## 리뷰어 의견 요지
|
|
112
|
+
|
|
113
|
+
- **`LottoMaker` *협력자 주입***.
|
|
114
|
+
- **`LottoGenerator` 인터페이스의 *목적 = 구현체 무지***. *수동/자동 분리*는 본질 위반.
|
|
115
|
+
- **`RandomLottoGenerator` *도메인 위치* 의문** — *키오스크/종이* 시나리오.
|
|
116
|
+
- **검증 중복 제거**.
|
|
117
|
+
- **`Rank.MISS` *NullObject*** = null 회피.
|
|
118
|
+
- **파라미터 = *불변 List***.
|
|
119
|
+
- **위임 시 *명시 메서드 우선*** — 위임 메서드가 *외부 조립 유혹*.
|
|
120
|
+
- **`getOrDefault` vs `getOrElse`** — *eager vs lazy*.
|
|
121
|
+
- **`INPUT_XX` 네이밍 *UI 결합 회피***.
|
|
122
|
+
- **변수 이름 *의미 부여***.
|
|
123
|
+
- **`println` 디버깅 잔여물**.
|
|
124
|
+
|
|
125
|
+
- **대표 인용:**
|
|
126
|
+
> 인터페이스로 만들어지게 되면서 기대할 수 있는 것은 *구현에 관심없이 로또 번호를 반환하는 것*을 생각할 수 있습니다.
|
|
127
|
+
> — @laco-dev on `src/main/kotlin/domain/LottoMaker.kt`
|
|
128
|
+
|
|
129
|
+
> 따로 만든다는 것 자체가 *근본적으로 인터페이스로 만들 이유가 없게 되지 않을까요*?
|
|
130
|
+
> — @laco-dev on `src/main/kotlin/domain/LottoGenerator.kt`
|
|
131
|
+
|
|
132
|
+
> 객체가 해야 할 책임과 비즈니스 로직을 *외부에서 뺏어서 작성할 수 있다는 의중성은 잘 염두*해 두시면 좋겠습니다.
|
|
133
|
+
> — @laco-dev on `src/main/kotlin/domain/Lottos.kt`
|
|
134
|
+
|
|
135
|
+
> getOrDefault() 함수는 *실제 값을 가져오기 먼저 호출*이 됩니다.
|
|
136
|
+
> — @laco-dev on `src/main/kotlin/domain/WinningResult.kt`
|
|
137
|
+
|
|
138
|
+
## 얻은 교훈
|
|
139
|
+
|
|
140
|
+
- **`LottoMaker` *협력자 주입*** — *new RandomGenerator()*는 *결합 강제*. *생성자/세터/인터페이스 주입* 3방법.
|
|
141
|
+
- **인터페이스 *목적 = 사용자가 구현체 모름*** — *수동/자동 인터페이스 분리*는 *목적 위배*. **공통 시그니처**만이 본질.
|
|
142
|
+
- **`RandomLottoGenerator` *도메인 위치* 의문** — *키오스크/종이* 시나리오 시 *Generator 구현체는 Controller가 선택*.
|
|
143
|
+
- **`Rank.MISS` = *NullObject 패턴*** — `Rank.from(): Rank?`보다 `Rank.from(): Rank = MISS`가 *호출자 null 처리 불요*.
|
|
144
|
+
- **파라미터 = *불변 List<T>*** — `MutableList` 외부 노출은 *침습적 수정 허용*.
|
|
145
|
+
- **위임 메서드 = *명시 메서드 우선*** — `: List<T> by numbers`로 `lottos.count { winningContains(it) }`이 *외부 조립*. `lottos.getMatchCount(winning)`이 *Tell-Don't-Ask*.
|
|
146
|
+
- **`getOrDefault` vs `getOrElse`** — *eager vs lazy*. *비용 있는 fallback*은 `getOrElse {. }`.
|
|
147
|
+
- **`INPUT_XX` *UI 결합 어휘***. 도메인은 *순수 도메인 단어*.
|
|
148
|
+
- **`println` 잔여물 = *PR 셀프 리뷰 부재***.
|
|
149
|
+
- ***Kotlin 컨벤션 프로퍼티 소문자***.
|
|
150
|
+
- **파라미터 이름 = *의미 있는 단어*** — `a`, `b`, `i`는 *컨벤셔널 인덱스*에만.
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# PR #62 — [로또] 하디 미션
|
|
2
|
+
|
|
3
|
+
- **Reviewee:** [@ii2001](https://github.com/ii2001)
|
|
4
|
+
- **PR:** https://github.com/woowacourse/kotlin-lotto/pull/62
|
|
5
|
+
- **단계:** 1단계
|
|
6
|
+
- **리뷰어:** @malibinYun
|
|
7
|
+
- **라인 코멘트:** 59
|
|
8
|
+
|
|
9
|
+
## 잘한 점 (설계 관점)
|
|
10
|
+
|
|
11
|
+
- **`Lotto`, `WinningNumber`, `LottoGenerator`, `LottoPrize` 분리**.
|
|
12
|
+
- **`Constant` 사용**.
|
|
13
|
+
|
|
14
|
+
## 못한 점 (설계 관점)
|
|
15
|
+
|
|
16
|
+
### 1. `Veilfier` — 오타 + 의미 불명
|
|
17
|
+
|
|
18
|
+
```kotlin
|
|
19
|
+
class Veilfier {. }
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
> Veilfier 는 어떤 뜻인가요? 검색해도 어떤 뜻인지 잘 모르겠네요
|
|
23
|
+
|
|
24
|
+
→ `Verifier`의 오타 + 의미 모호. 클래스명은 *검색해서 의미를 알 수 있어야*.
|
|
25
|
+
|
|
26
|
+
### 2. `Lotto.numbers: List<Int>` — LottoNumber 미추출
|
|
27
|
+
|
|
28
|
+
```kotlin
|
|
29
|
+
class Lotto(val numbers: List<Int>) {. }
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
> Int로 단일 로또 번호에 대한 제약 사항을 충분히 표현해낼 수 있을까요? 로또 번호 하나를 객체로써 의미를 담아보는건 어떨까요?
|
|
33
|
+
|
|
34
|
+
→ lotto의 핵심 안티패턴 (PR마다 반복).
|
|
35
|
+
|
|
36
|
+
### 3. `WinningNumber` — 값만 보유, 행위 없음
|
|
37
|
+
|
|
38
|
+
```kotlin
|
|
39
|
+
class WinningNumber(val number: Int) {
|
|
40
|
+
// 행위 없음
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
> 이 객체는 단순히 값을 가지고있는 것 외에 별다른 역할을 가지고 있지 않고 있네요 이 객체가 맡을만한 일이 무엇인지 찾아 이 객체에게 부여해보는 건 어떨까요?
|
|
45
|
+
|
|
46
|
+
→ 값 객체 만들었으면 *행위*도 부여. 매칭 판정, 보너스 일치 여부 등.
|
|
47
|
+
|
|
48
|
+
### 4. `Constant` god-class — 자가 의문 유도
|
|
49
|
+
|
|
50
|
+
```kotlin
|
|
51
|
+
object Constant {
|
|
52
|
+
const val LOTTO_PRICE = 1000
|
|
53
|
+
const val MIN = 1
|
|
54
|
+
.
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
> 이 값들을 하나의 상수 클래스로 묶은 이유가 궁금해요! 필요한 객체가 갖고 있는 것과 어떤 차이점과 장단점이 있었나요?
|
|
59
|
+
|
|
60
|
+
### 5. `LottoGenerator` 테스트 없음
|
|
61
|
+
|
|
62
|
+
```kotlin
|
|
63
|
+
class LottoGenerator { fun generate(): Lotto =. }
|
|
64
|
+
// ⚠ 테스트 없음 (랜덤 의존)
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
> LottoGenerator에 대한 테스트 코드가 존재하지 않네요 이 객체는 어떻게 테스트 가능하게 만들어볼 수 있을까요? 자동차 경주에서의 랜덤 테스트를 어떻게 만들었는지 다시 되새겨보아요
|
|
68
|
+
|
|
69
|
+
→ NumberGenerator 인터페이스로 추상화. racingcar에서 학습한 패턴.
|
|
70
|
+
|
|
71
|
+
### 6. `LottoPrize`에 뷰 요소
|
|
72
|
+
|
|
73
|
+
```kotlin
|
|
74
|
+
enum class LottoPrize(val countOfMatch: Int, val prize: Int, val message: String) {. }
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
> 도메인 로직에 뷰 요소가 들어있네요!
|
|
78
|
+
|
|
79
|
+
→ lotto의 또 다른 반복 안티패턴 — Rank/Prize enum에 표시 문자열.
|
|
80
|
+
|
|
81
|
+
## 리뷰어 의견 요지
|
|
82
|
+
|
|
83
|
+
리뷰어 @malibinYun의 가르침:
|
|
84
|
+
|
|
85
|
+
1. **클래스명 = 검색해서 의미 추적 가능해야** — `Veilfier` 오타.
|
|
86
|
+
|
|
87
|
+
2. **`LottoNumber` 추출** — lotto 마스터 키.
|
|
88
|
+
|
|
89
|
+
3. **값 객체에 행위 부여** — 값만 있으면 그저 wrapper.
|
|
90
|
+
|
|
91
|
+
4. **god-class `Constant` vs 필요한 객체가 자체 보유**.
|
|
92
|
+
|
|
93
|
+
5. **테스트 가능성 = racingcar 학습 적용** — NumberGenerator 추상화.
|
|
94
|
+
|
|
95
|
+
- **대표 인용:**
|
|
96
|
+
> 이 객체는 단순히 값을 가지고있는 것 외에 별다른 역할을 가지고 있지 않고 있네요 이 객체가 맡을만한 일이 무엇인지 찾아 이 객체에게 부여해보는 건 어떨까요?
|
|
97
|
+
>
|
|
98
|
+
> — @malibinYun on `src/main/kotlin/lotto/model/WinningNumber.kt`
|
|
99
|
+
|
|
100
|
+
## 얻은 교훈
|
|
101
|
+
|
|
102
|
+
- **클래스명 = 검색 가능한 단어** — 오타/조어는 동료가 의미 추정 어려움.
|
|
103
|
+
- **값 객체에 행위 부여 필수**. 값만 있는 wrapper는 *얇은 위장*. 행위가 있어야 객체.
|
|
104
|
+
- **이전 미션 (racingcar) 학습 적용** — NumberGenerator 추상화는 racingcar에서 받은 가르침. 동일 패턴.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# PR #88 — [로또] 하디 2단계 미션
|
|
2
|
+
|
|
3
|
+
- **Reviewee:** [@ii2001](https://github.com/ii2001)
|
|
4
|
+
- **PR:** https://github.com/woowacourse/kotlin-lotto/pull/88
|
|
5
|
+
- **단계:** 2단계
|
|
6
|
+
- **리뷰어:** @malibinYun
|
|
7
|
+
- **라인 코멘트:** 6
|
|
8
|
+
|
|
9
|
+
## 핵심 지적
|
|
10
|
+
|
|
11
|
+
- **수동 티켓 생성을 적절한 객체로 이동**.
|
|
12
|
+
- **테스트 픽스처 적용**.
|
|
13
|
+
- **1단계 피드백 (PR #62) 유지** — `LottoPrize`에 뷰 요소.
|
|
14
|
+
|
|
15
|
+
> https://github.com/woowacourse/kotlin-lotto/pull/62#discussion_r1502612429 여전히 유효한 피드백입니다.
|
|
16
|
+
|
|
17
|
+
## 얻은 교훈
|
|
18
|
+
|
|
19
|
+
- **이전 라운드 피드백 *지속적 검증***. 2단계에서 1단계 피드백 미반영은 *학습 후퇴*.
|
|
20
|
+
- **테스트 픽스처 = `@BeforeEach`** — 반복 setup 제거.
|