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,166 @@
|
|
|
1
|
+
# PR #49 — [써니] 2단계 로또
|
|
2
|
+
|
|
3
|
+
- **Reviewee:** [@inseonyun](https://github.com/inseonyun)
|
|
4
|
+
- **PR:** https://github.com/woowacourse/kotlin-lotto/pull/49
|
|
5
|
+
- **단계:** 2단계 (수동 로또)
|
|
6
|
+
- **리뷰어:** @namjackson (잭슨)
|
|
7
|
+
- **라인 코멘트:** 17
|
|
8
|
+
|
|
9
|
+
## 잘한 점 (설계 관점)
|
|
10
|
+
|
|
11
|
+
- **`Lottos.operator fun plus`** — 컬렉션 결합을 *연산자*로. 리뷰어 칭찬: "operator 👍 👍".
|
|
12
|
+
- **`PurchaseMoney`, `LottoCount`, `LottoPrice`, `LottoTicket`** — 원시값 포장 4개.
|
|
13
|
+
- **`tryAndRerun` 유틸** — *입력 실패 시 재시도*를 한 곳에서.
|
|
14
|
+
- **Controller 슬림화** — 후속 라운드에서 잭슨이 "Controller 내의 코드가 많이 줄었네요 👍 👍" 인정.
|
|
15
|
+
|
|
16
|
+
## 못한 점 (설계 관점)
|
|
17
|
+
|
|
18
|
+
### 1. 자동 로또 수 계산 = *Controller*에서 수행
|
|
19
|
+
|
|
20
|
+
```kotlin
|
|
21
|
+
// World.kt
|
|
22
|
+
private fun initLottos(purchaseLottoCount: LottoCount, manualLottoCount: LottoCount): Lottos {
|
|
23
|
+
val store = LottoStore()
|
|
24
|
+
val autoLottoCount = purchaseLottoCount.calculateAutoLottoCount(manualLottoCount)
|
|
25
|
+
val manualLottos = store.buyManualLotto(manualLottoCount.value, *initManualLotto(manualLottoCount))
|
|
26
|
+
val autoLottos = store.buyAutoLotto(autoLottoCount.value)
|
|
27
|
+
val totalLottos = store.mergeLottos(manualLottos, autoLottos)
|
|
28
|
+
.
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
리뷰어: "자동 로또를 *몇 장 사는지에 대한 부분은 money와 manualLottoCount를 입력받은 LottoStore에서 계산*되어야 하는 작업이 아닐까요?" + "store에서 값을 받아와서, Controller에서 처리하기보단, *Store에게 책임을 주어, 내부적으로 동작이 처리되게 메시지를 전달*해 보아도 좋을 거 같아요! Store에 PurchaseMoney, Array<Lotto>의 정보만 있다면, *수동 로또와 자동 로또를 반환할 수 있지 않을까요*?" — *Tell, Don't Ask*.
|
|
33
|
+
|
|
34
|
+
### 2. InputView vs OutputView vs 화면 단위 — 학생 자가 의문
|
|
35
|
+
|
|
36
|
+
학생: "입력을 위한 문구 출력의 경우 현재 *컨트롤러에서 inputView의 함수를 호출할 때 같이 호출*하며 사용하고 있는데, *InputView 클래스 내의 함수에서 OutputView를 호출*해줘도 문제 되지 않는지 궁금합니다." 리뷰어: "View라는 것은 *입출력을 모두 포함*하기 때문에, InputView, OutputView로 나뉘어서, InputView에선 입력만 받고, OutputView에선 출력만 받는 역할을 분리하게 되어, *View에 대한 정의가 모호*해진 것 같아요. *입/출력이라는 기능으로 분리하는 것이 아니라, 화면 단위나 행위 단위로 나눠* 보는 건 어떨까요? InputView에서는 *유저의 로또 정보를 입력을 받는 단계의 UI*를, OutputView에서는 *로또 결과 출력을 하는 단계의 UI*로 분리." — *입력/출력의 기능 분리*가 *행위 단위 분리*에 비해 응집도 낮음.
|
|
37
|
+
|
|
38
|
+
### 3. View에서 *반복 입력* vs 도메인 검증 — 학생 자가 의문
|
|
39
|
+
|
|
40
|
+
학생: "입력에 대한 예외와 반복 입력을 View에서 진행하고, *원시값 포장과 이에 따른 검증을 도메인에서 진행*하게 됐을 때, *그 검증 예외의 경우도 반복 입력*을 수행해 정상적인 값을 받도록 해야 할지, 아니면 프로그램이 종료되도록 할지 고민입니다." 리뷰어: "요구사항이 명확하지 않기 때문에 *선택의 문제*라고 생각합니다! 반복 입력을 수행하게 된다면, ux적으로는 좋지만, *입력값이 아닌 다른 에러들까지 반복이 실행될 가능성*도 있고, *입력으로 인한 에러가 아닌 다른 에러가 발생했을 때의 통일성*에 대한 부분도 고려해야 할 부분이라고 생각이 들어요. 사실 입력 값에 대한 부분인 만큼, *입력받는 View에서도 검증을 하는 게 깔끔*하기도 해요. 현업에서는 *명확한 요구사항과 명세서가 작성되어야 하기도 하고, 관련된 담당자들과의 의사소통으로 결정*되는 부분도 있지만, 로또 프로그램은 미션이니 만큼 *자유롭게 구현*하셔도 좋을 거 같습니다!" — *시스템 경계*는 *명세서*에 의존.
|
|
41
|
+
|
|
42
|
+
### 4. `Array<Lotto>`는 무엇? — *발행 전 티켓* 모델링
|
|
43
|
+
|
|
44
|
+
```kotlin
|
|
45
|
+
private fun initManualLotto(manualLottoCount: LottoCount): Array<Lotto> {. }
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
리뷰어: "Array<Lotto>는 무엇을 의미하는 것일까요? 얼핏 보았을 때 *Lottos와 무엇이 다를까 고민이 생길 것* 같아요. *발행하기 전 로또라면, LottoTicket 같은 클래스*를 만들어보면 어떨까요?" + (InputView 내): "Lotto 생성에 대한 *책임은 LottoStore의 ManualLottoGenerator에게 위임*해 보면 어떨까요? 아직 *발행 전 티켓은 LottoTicket과 같은 클래스로 전달*되어도 좋을 거 같단 생각이 들어요!" — *상태가 다른 객체*는 *다른 타입*.
|
|
49
|
+
|
|
50
|
+
### 5. View가 *구매 가능 매수* 계산
|
|
51
|
+
|
|
52
|
+
```kotlin
|
|
53
|
+
private fun readManualLottoCount(purchaseMoney: Int): Int {
|
|
54
|
+
val input = readln()
|
|
55
|
+
require(input.toIntOrNull() != null) { ERROR_MESSAGE_ONLY_NUMBER }
|
|
56
|
+
if (input.toInt() != 0)
|
|
57
|
+
require((purchaseMoney / (input.toInt() * LottoPrice.DEFAULT_LOTTO_PRICE) > 0)) { ERROR_MESSAGE_AVAILABLE_COUNT }
|
|
58
|
+
return input.toInt()
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
리뷰어: "계산되는 로직은 *도메인 로직으로 이동*해 보면 어떨까요? *구매 가능한 로또는 purchaseMoney에서 관리*되어도 좋을 거 같아요!" — *View의 검증*은 *형식*만, *비즈니스 규칙*은 도메인.
|
|
63
|
+
|
|
64
|
+
### 6. `data class` vs 일반 class — 학생 자가 의문
|
|
65
|
+
|
|
66
|
+
```kotlin
|
|
67
|
+
class Lotto private constructor(private val numbers: Set<LottoNumber>) {
|
|
68
|
+
override fun hashCode(): Int = numbers.hashCode()
|
|
69
|
+
override fun equals(other: Any?): Boolean {. }
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
리뷰어: "data 클래스와 일반 클래스는 *어떤 차이*가 있을까요?" 학생: "기존 동등성 비교를 위해 data class로 선언을 해 주었으나, *주 생성자를 private constructor로 선언하는 과정에서 copy 메소드를 통해 주 생성자가 노출 된다는 IDE 상에서의 문구*를 확인하여, 이를 막고자 data class가 아닌 *일반 클래스로 선언 후 equals와 hashCode 함수를 오버라이드* 했습니다! 혹시 이 경우 어떤 방법으로 코드 작성을 해야 하나요?" 리뷰어: "private constructor를 놓쳤었네요. *트레이드오프에 대한 선택의 문제*인 것 같아요! 현재 Lotto의 *팩토리 함수에 중요한 로직이 없기 때문에 private constructor를 강제하지 않아도 좋을 거 같긴* 한데, *통일성이나, 이후 팩토리 함수의 로직이 추가될 수 있으니, 선택의 문제*인 것 같아요." — *생성자 통제* vs *data class 편의* 트레이드오프.
|
|
74
|
+
|
|
75
|
+
### 7. `LottoStore`의 `buyManualLotto`/`buyAutoLotto` 외부 노출 — 캡슐화
|
|
76
|
+
|
|
77
|
+
```kotlin
|
|
78
|
+
class LottoStore {
|
|
79
|
+
fun buyManualLotto(): Lottos {. }
|
|
80
|
+
fun buyAutoLotto(): Lottos {. }
|
|
81
|
+
fun makeLottos(): Lottos = mergeLottos(buyManualLotto(), buyAutoLotto())
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
리뷰어: "buyManualLotto, buyAutoLotto는 *테스트 코드 외에선 사용되지 않아요. 외부로 노출될 필요가 없을 것 같아요*! 테스트도 변경해 보아요!" — *테스트를 위한 가시성 확장* 안티패턴.
|
|
86
|
+
|
|
87
|
+
### 8. `var lottoCount` *상태값* — Backing field 권장
|
|
88
|
+
|
|
89
|
+
```kotlin
|
|
90
|
+
class LottoStore(.) {
|
|
91
|
+
var lottoCount = purchaseMoney.getPurchaseLottoCount()
|
|
92
|
+
private set
|
|
93
|
+
|
|
94
|
+
fun buyManualLotto(): Lottos {
|
|
95
|
+
lottoCount -= manualLottoTickets.size // ⚠ 상태 변경
|
|
96
|
+
.
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
리뷰어: "변수에 대한 *책임이 모호*한 거 같아요. *lottoCount는 어떤 것을 의미할까요*? *상태값을 가질 필요는 없을 거 같아요*, 또한 외부에 노출되지 않아도 될 거 같아요!" 제안:
|
|
102
|
+
```kotlin
|
|
103
|
+
private val autoLottoCount get() = purchaseMoney.getPurchaseLottoCount() - manualLottoTickets.size
|
|
104
|
+
```
|
|
105
|
+
*파생값은 계산식*. 학생: "Controller에서 *수동, 자동 로또 구매 결과 출력*을 호출할 때, *각각의 로또 개수를 출력해야 해서 public으로 변수를 선언*했었는데, *private으로 숨기고, 이를 따로 getAutoLottoCount라는 함수를 구현*해서 반환해 주는 방식으로 해도 상관이 없을까요!? *직접적인 변수 접근을 할 수 없어 이와 같은 방법이 좋아 보이지만 필요 없는 함수를 결과 출력을 위해 굳이 생성*하는 게 아닌가 싶어 의문이 듭니다!" 리뷰어: "써니님 말씀대로 *불필요해 보이는 함수가 되었네요. 제가 커뮤니케이션 미스가 있었네요* 🙏 *상태값을 가지는 변수보단 Backing field를 활용*을 추천하는 코멘트였습니다! *autoLottoCount는 getter만 있기 때문에 외부에 노출되어도 상관없을 것* 같아요!" — *별도 함수 vs property getter*는 Kotlin에서 *property*가 자연.
|
|
106
|
+
|
|
107
|
+
### 9. `if`문 *중괄호 생략*
|
|
108
|
+
|
|
109
|
+
```kotlin
|
|
110
|
+
fun checkManualLottoCount(manualLottoCount: Int): Int {
|
|
111
|
+
if (manualLottoCount != 0)
|
|
112
|
+
require(value / (manualLottoCount * LottoPrice.DEFAULT_LOTTO_PRICE) > 0) { ERROR_MESSAGE_AVAILABLE_COUNT }
|
|
113
|
+
.
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
리뷰어: "if문이 2줄 이상 되면, `{}` 중괄호 *생략하지 않는 게 좋을 거 같아요*!" — *암묵 블록 경계*는 버그 유발(Apple goto fail).
|
|
118
|
+
|
|
119
|
+
### 10. 테스트에 *범위로 LottoNumber 생성*
|
|
120
|
+
|
|
121
|
+
```kotlin
|
|
122
|
+
fun generateLotto(startLottoNumber: Int, endLottoNumber: Int): List<LottoNumber> =
|
|
123
|
+
(startLottoNumber..endLottoNumber).map { LottoNumber(it) }
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
리뷰어: "*range로 만들어서 generate해 주기 보다 List<Int>로 받아* 보면 어떨까요? *좀 더 명확*할 거 같아요!" — *추상화*보다 *명시적 케이스*.
|
|
127
|
+
|
|
128
|
+
## 리뷰어 의견 요지
|
|
129
|
+
|
|
130
|
+
- **Tell, Don't Ask** — `LottoStore`가 *수동/자동 수 + 발행*까지 직접.
|
|
131
|
+
- **InputView/OutputView 기능 분리는 *응집도 낮음*** — *화면/행위 단위*로 분리.
|
|
132
|
+
- **반복 입력 = *명세에 따른 선택***. View 형식 vs 도메인 정책 일관성 필요.
|
|
133
|
+
- **발행 전 티켓은 *별도 타입* (`LottoTicket`)** — 상태가 다른 객체는 타입도 다름.
|
|
134
|
+
- **View의 비즈니스 계산 X** — *구매 가능 매수*는 `PurchaseMoney`.
|
|
135
|
+
- **`data class` vs `private constructor`** = *트레이드오프*.
|
|
136
|
+
- **테스트만을 위한 가시성 확장 X**.
|
|
137
|
+
- **`var` 상태값 → *property getter (backing field)***.
|
|
138
|
+
- **if 2줄 이상 = 중괄호 필수**.
|
|
139
|
+
- **테스트 픽스처는 *명시적 List*가 *range*보다 명확**.
|
|
140
|
+
|
|
141
|
+
- **대표 인용:**
|
|
142
|
+
> 자동 로또를 *몇 장 사는지에 대한 부분은 money와 manualLottoCount를 입력받은 LottoStore에서 계산*되어야 하는 작업이 아닐까요?
|
|
143
|
+
> — @namjackson on `src/main/kotlin/lotto/controller/World.kt`
|
|
144
|
+
|
|
145
|
+
> 입/출력이라는 기능으로 분리하는 것이 아니라, *화면 단위나 행위 단위로 나눠* 보는 건 어떨까요?
|
|
146
|
+
> — @namjackson on `src/main/kotlin/lotto/view/InputView.kt`
|
|
147
|
+
|
|
148
|
+
> 아직 *발행 전 티켓은 LottoTicket과 같은 클래스로 전달*되어도 좋을 거 같단 생각이 들어요!
|
|
149
|
+
> — @namjackson on `src/main/kotlin/lotto/view/InputView.kt`
|
|
150
|
+
|
|
151
|
+
> 상태값을 가지는 변수보단 *Backing field를 활용*을 추천하는 코멘트였습니다!
|
|
152
|
+
> — @namjackson on `src/main/kotlin/lotto/model/LottoStore.kt`
|
|
153
|
+
|
|
154
|
+
## 얻은 교훈
|
|
155
|
+
|
|
156
|
+
- **Tell, Don't Ask** — `purchaseMoney.calc - manualCount` 같은 *Controller 계산*은 *Store에 메시지*로.
|
|
157
|
+
- **View 분리는 *기능*이 아니라 *화면/행위***. InputView/OutputView는 *기능 분리*로 *응집도 낮은* 안티패턴이 됨.
|
|
158
|
+
- **반복 입력의 *경계*** — *형식 오류*는 View에서 재시도, *도메인 규칙 위반*은 일관 정책 필요.
|
|
159
|
+
- **상태가 다른 객체는 *다른 타입*** — *발행 전 LottoTicket* vs *발행 후 Lotto*.
|
|
160
|
+
- **View의 비즈니스 계산 금지** — *구매 가능 매수*는 `PurchaseMoney.getPurchaseLottoCount()`.
|
|
161
|
+
- **`data class` vs `private constructor` 충돌** — *copy 노출*이 부담이면 일반 class + equals/hashCode. 단 *팩토리 로직이 없으면 트레이드오프*.
|
|
162
|
+
- **테스트를 위한 *public 노출*은 안티패턴** — *내부 메서드 테스트* 필요하면 *통합 시나리오*로.
|
|
163
|
+
- **`var` 상태값 → *property getter*** — *파생값*은 *계산식*. Kotlin은 `val x get() =.`이 *함수*보다 자연.
|
|
164
|
+
- **`if` 2줄 이상 = `{}` 필수** — Apple goto fail 사례처럼 *암묵 블록*은 버그 유발.
|
|
165
|
+
- **테스트 픽스처는 *명시적*** — `(1..5)` 범위보다 `listOf(1,2,3,4,5)`가 *의도*를 드러냄.
|
|
166
|
+
- **리뷰어도 *커뮤니케이션 미스*를 인정** — "써니님 말씀대로 불필요해 보이는 함수가 되었네요. *제가 커뮤니케이션 미스가 있었네요* 🙏". 후배가 의문을 제기하는 *대화의 가치*.
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
# PR #16 — [글로] 1단계 로또
|
|
2
|
+
|
|
3
|
+
- **Reviewee:** [@ippnsj](https://github.com/ippnsj)
|
|
4
|
+
- **PR:** https://github.com/woowacourse/kotlin-lotto/pull/16
|
|
5
|
+
- **단계:** 1단계
|
|
6
|
+
- **리뷰어:** @laco-dev
|
|
7
|
+
- **라인 코멘트:** 75
|
|
8
|
+
|
|
9
|
+
## 잘한 점 (설계 관점)
|
|
10
|
+
|
|
11
|
+
- **`LotteryNumber` 값 객체 도입**, `Lottery` 일급 컬렉션.
|
|
12
|
+
- **`LotteriesGenerator` 인터페이스 + 람다 주입 시도** (SAM).
|
|
13
|
+
- **`PurchaseAmount` 값 객체** — 금액 도메인 분리.
|
|
14
|
+
- **`Revenue` 별도 객체** — 수익률 분리.
|
|
15
|
+
|
|
16
|
+
## 못한 점 (설계 관점)
|
|
17
|
+
|
|
18
|
+
### 1. `NumberOfRank` 이름과 데이터 불일치
|
|
19
|
+
|
|
20
|
+
```kotlin
|
|
21
|
+
class NumberOfRank(val numbers: Map<String, Int>) {. }
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
> 이름은 NumberOfRank인데, 키값인 String은 무엇을 의미하는지? 값인 Int는 Number라는 것인데 이 Number는 무엇을 의미하는지?
|
|
25
|
+
|
|
26
|
+
→ `Map<Rank, Int>`로 키 타입을 도메인 어휘로. `numbers`라는 필드명도 모호 (`countByRank` 등).
|
|
27
|
+
|
|
28
|
+
### 2. `Rank`가 String 파라미터 받음 (상금 정보 외부에서)
|
|
29
|
+
|
|
30
|
+
```kotlin
|
|
31
|
+
enum class Rank(val description: String, val price: Int) {
|
|
32
|
+
FIRST("6개 일치", 2_000_000_000),
|
|
33
|
+
.
|
|
34
|
+
fun calculatePrize(count: Int): Int =.
|
|
35
|
+
}
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
> Rank 스스로 상금을 계산할 방법이 있는데 String을 파라미터로 받는 이유는 무엇일까요?
|
|
39
|
+
|
|
40
|
+
→ Rank가 자기 상금 정보를 갖고 있으면 외부에서 받을 필요 없음.
|
|
41
|
+
|
|
42
|
+
### 3. `description`이 도메인에 들어옴 (UI 누수)
|
|
43
|
+
|
|
44
|
+
```kotlin
|
|
45
|
+
enum class Rank(val description: String, val price: Int) {
|
|
46
|
+
FIRST("6개 일치",.), // ⚠ UI 표현이 enum 데이터
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
> description은 UI영역의 관심사이지 않을까요?
|
|
51
|
+
|
|
52
|
+
`Revenue`에도 description 누수 — 같은 패턴.
|
|
53
|
+
|
|
54
|
+
### 4. `WinningResultCalculator` — 이름과 책임 불일치
|
|
55
|
+
|
|
56
|
+
```kotlin
|
|
57
|
+
class WinningResultCalculator {
|
|
58
|
+
fun calculate(.): Double =. // ⚠ 수익률 계산만 함
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
> 로또 게임에 대한 승부 결과가 하는 역할은 무엇일까요? 현재는 당첨금을 계산해주는 역할만 수행하고 있기 때문에 객체 이름과는 다소 맞지 않아 보입니다. 승부 결과를 만들어내는 역할로 본다면 NumberOfRank를 만드는 역할도 같이 할 수 있을 것 같습니다.
|
|
63
|
+
|
|
64
|
+
→ 두 선택지:
|
|
65
|
+
- 이름에 맞게 책임 확장 (`WinningResult`가 NumberOfRank + 수익률 둘 다)
|
|
66
|
+
- 책임에 맞게 이름 좁히기 (`ProfitCalculator`)
|
|
67
|
+
|
|
68
|
+
### 5. `Lottery`가 `Bonus`인지 알아야 하는 책임
|
|
69
|
+
|
|
70
|
+
```kotlin
|
|
71
|
+
class Lottery(.) {
|
|
72
|
+
fun match(other: Lottery, bonusNumber: LotteryNumber): Rank {
|
|
73
|
+
val count = numbers.count { it in other.numbers }
|
|
74
|
+
val hasBonus = numbers.contains(bonusNumber) // ⚠ Lottery가 보너스를 알아야 함
|
|
75
|
+
return Rank.of(count, hasBonus)
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
> 파라미터로 받은 로또 번호가 일치하는지 확인하기 때문에 이 숫자가 Bonus인지 아닌지는 알 필요가 없지 않을까요?
|
|
81
|
+
|
|
82
|
+
→ `WinningLottery` (Lottery + Bonus를 모두 가진 별도 객체)가 `match(lottery): Rank`를 책임.
|
|
83
|
+
|
|
84
|
+
### 6. View에서 try-catch + 중복
|
|
85
|
+
|
|
86
|
+
```kotlin
|
|
87
|
+
fun readPurchaseAmount(): Int {
|
|
88
|
+
while (true) {
|
|
89
|
+
try {
|
|
90
|
+
return readLine()!!.toInt()
|
|
91
|
+
} catch (e: NumberFormatException) {
|
|
92
|
+
println(".")
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
→ 재귀로 더 깔끔:
|
|
99
|
+
|
|
100
|
+
```kotlin
|
|
101
|
+
fun readPurchaseAmount(): Int {
|
|
102
|
+
val result = readLine().toIntOrNull()
|
|
103
|
+
if (result != null) return result
|
|
104
|
+
println(.)
|
|
105
|
+
return readPurchaseAmount()
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### 7. 테스트 생성 반복 → Fake Constructor 미적용
|
|
110
|
+
|
|
111
|
+
```kotlin
|
|
112
|
+
val lottery = Lottery(listOf(
|
|
113
|
+
LotteryNumber(1), LotteryNumber(10), LotteryNumber(20),.
|
|
114
|
+
))
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
> Fake Constructor 같은 개념을 사용할 수 있습니다.
|
|
118
|
+
> ```kotlin
|
|
119
|
+
> val lottery = Lottery(1, 10, 20, 30, 40, 45)
|
|
120
|
+
> private fun Lottery(vararg numbers: Int): Lottery {. }
|
|
121
|
+
> ```
|
|
122
|
+
|
|
123
|
+
테스트 가독성 + 작성 비용 ↓.
|
|
124
|
+
|
|
125
|
+
## 리뷰어 의견 요지
|
|
126
|
+
|
|
127
|
+
리뷰어 @laco-dev의 가르침:
|
|
128
|
+
|
|
129
|
+
1. **enum의 `description` = UI 누수**. lotto에서 가장 흔한 안티패턴 중 하나. UI 표현이 도메인 데이터에 박히면 UI 변경이 도메인 변경.
|
|
130
|
+
|
|
131
|
+
2. **이름과 책임의 일치**. `WinningResultCalculator`가 수익률만 계산 = 이름 너무 큼. 두 선택 중 일관성.
|
|
132
|
+
|
|
133
|
+
3. **Fake Constructor** 패턴 — 테스트 가독성 + 재사용. lotto는 다수 LotteryNumber를 만들어야 해서 특히 효과적.
|
|
134
|
+
|
|
135
|
+
4. **재귀 입력** = while + try-catch보다 depth 낮음.
|
|
136
|
+
|
|
137
|
+
5. **Tell-Don't-Ask** — Lottery가 Bonus를 알지 않게, WinningLottery가 match 책임.
|
|
138
|
+
|
|
139
|
+
- **대표 인용:**
|
|
140
|
+
> 이름은 NumberOfRank인데, 키값인 String은 무엇을 의미하는지? 값인 Int는 Number라는 것인데 이 Number는 무엇을 의미하는지?
|
|
141
|
+
>
|
|
142
|
+
> — @laco-dev on `src/main/kotlin/lotto/domain/NumberOfRank.kt`
|
|
143
|
+
|
|
144
|
+
> 로또 게임에 대한 승부 결과가 하는 역할은 무엇일까요? 현재는 당첨금을 계산해주는 역할만 수행하고 있기 때문에 객체 이름과는 다소 맞지 않아 보입니다.
|
|
145
|
+
>
|
|
146
|
+
> — @laco-dev on `src/main/kotlin/lotto/domain/WinningResultCalculator.kt`
|
|
147
|
+
|
|
148
|
+
## 얻은 교훈
|
|
149
|
+
|
|
150
|
+
- **`Map<String, Int>`는 god-map**. Key가 String이면 호출처에서 매번 정확한 키를 알아야 함. `Map<Rank, Int>`로 타입 안전성.
|
|
151
|
+
- **enum 데이터에 UI 표현 (`description`) 박지 말 것** — lotto의 특히 빈번한 안티패턴.
|
|
152
|
+
- **클래스명 = 책임의 한 문장 요약**. `WinningResultCalculator`가 수익률만 = 이름과 어긋남. 책임을 *확장*하거나 *이름을 좁히기*.
|
|
153
|
+
- **Fake Constructor** = 테스트 부생성자. `Lottery(1, 10, 20, 30, 40, 45)` 같은 짧은 생성. lotto처럼 다수의 값 객체를 조립해야 하는 도메인에 효과적.
|
|
154
|
+
- **재귀 입력 패턴**. while+try-catch보다 깔끔. *단, 입력 재시도 횟수가 제한적*인 콘솔 환경에서 안전.
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
# PR #55 — [글로] 2단계 로또
|
|
2
|
+
|
|
3
|
+
- **Reviewee:** [@ippnsj](https://github.com/ippnsj)
|
|
4
|
+
- **PR:** https://github.com/woowacourse/kotlin-lotto/pull/55
|
|
5
|
+
- **단계:** 2단계 (수동 로또)
|
|
6
|
+
- **리뷰어:** @laco-dev (라코)
|
|
7
|
+
- **라인 코멘트:** 20 (리뷰어 12 + 학생 8)
|
|
8
|
+
|
|
9
|
+
## 잘한 점 (설계 관점)
|
|
10
|
+
|
|
11
|
+
## 못한 점 (설계 관점)
|
|
12
|
+
|
|
13
|
+
### 1. `PurchaseAmount` *불필요한 관심사 다수*
|
|
14
|
+
|
|
15
|
+
```kotlin
|
|
16
|
+
class PurchaseAmount(.) {
|
|
17
|
+
fun numberOfLottos(): Int
|
|
18
|
+
fun manualLottos(): Int // ⚠ Amount가 수동을 앎?
|
|
19
|
+
fun autoLottos(): Int
|
|
20
|
+
}
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
리뷰어: "*PurchaseAmount가 불필요한 관심사를 많이 가지게 된 것* 같습니다. *구매 금액 입장에서 로또 갯수나 수동 로또 등의 정보는 알 필요가 없지 않을까요? 자동과 수동은 하나의 상위 개념으로 구조화가 되어야 맞는 방법*이지 않을까 생각해요
|
|
24
|
+
```
|
|
25
|
+
주문서 {
|
|
26
|
+
주문 금액
|
|
27
|
+
수동 갯수
|
|
28
|
+
자동 갯수
|
|
29
|
+
}
|
|
30
|
+
```" — *Order* 도메인.
|
|
31
|
+
|
|
32
|
+
### 2. *`Quantity` 별도 객체* — 양수 보장
|
|
33
|
+
|
|
34
|
+
리뷰어: "*항상 양수만 가지는 개념의 Quantity를 별도의 객체로 만들어* 보세요" — *원시값 포장 + invariant*.
|
|
35
|
+
|
|
36
|
+
### 3. *자동/수동 의미 함수명에 숨김*
|
|
37
|
+
|
|
38
|
+
```kotlin
|
|
39
|
+
fun getQuantity(): Int // ⚠ 자동인지 수동인지 모름
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
리뷰어: "*자동, 수동 의미가 여기저기 숨겨져 있어서 이 함수가 무슨 Quantity를 반환하는지 파악이 어렵게 느껴*집니다. *함수 이름만 보면, 단순히 양의 정수를 반환하는데, 실제로는 수동 로또 갯수를 반환*하고 있습니다. *자동, 수동처럼 의미를 여러 개 가지는 경우라면 함수의 이름에 포함을 시켜 주는 게 좋겠*습니다".
|
|
43
|
+
|
|
44
|
+
### 4. *`mutableList()` → `List(size) {. }`*
|
|
45
|
+
|
|
46
|
+
리뷰어: "*mutableList() 대신 List를 생성하기 위한 빌더 함수를 활용*해 보세요." — 모든 PR 공통.
|
|
47
|
+
|
|
48
|
+
### 5. *오류 책임 위치* — InputView/Controller/OutputView?
|
|
49
|
+
|
|
50
|
+
리뷰어: "*오류가 발생했을 때 InputView에게 책임을 전달하는 게 맞는 순서일까요? 생성하는 과정에서 실패를 했을 수도 있고, InputView에서 실패를 했을 수도 있지는 않을까요? 입력을 받는 중에 실패한 것이라면, InputView에서 스스로 출력을 하고 컨트롤러에서 오류를 확인하는 목적이라면, 컨트롤러에서 콘솔에 출력을 할 수 있고 사용자에게 오류를 전달하고 싶다면, OutputView로 오류를 출력*할 수 있겠습니다." — *오류 출처 = 처리 책임*.
|
|
51
|
+
|
|
52
|
+
### 6. `LottoResult.totalPrize(ranks)` — 외부 조립
|
|
53
|
+
|
|
54
|
+
```kotlin
|
|
55
|
+
val ranks =.
|
|
56
|
+
val prize = lottoResult.totalPrize(ranks) // ⚠
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
리뷰어: "*총 상금을 계산하기 위해서 파라미터로 받는 ranks는 이미 LottoResult가 스스로 계산할 능력이 있지 않을까요? 외부에서 만들고 다시 함수로 넣어줄 필요가* 있을까요? 만약, LotteryResult가 아래와 같은 형태가 된다면 어떤 차이가 있을까요?
|
|
60
|
+
```kotlin
|
|
61
|
+
class LotteryResult(val winningLottery: WinningLottery, tickets: List<Lottery>) {. }
|
|
62
|
+
```"
|
|
63
|
+
|
|
64
|
+
### 7. *`val` 사용* — init에서 결정 가능
|
|
65
|
+
|
|
66
|
+
리뷰어: "*init 블록에서 결정되는 값이라면 val로 만들어도* 됩니다."
|
|
67
|
+
|
|
68
|
+
### 8. *코드 일관성* — `manualTickets`/`autoTickets`
|
|
69
|
+
|
|
70
|
+
리뷰어:
|
|
71
|
+
```kotlin
|
|
72
|
+
val manualTickets = publishManualTickets(.)
|
|
73
|
+
val autoTickets = publishAutoTickets(.)
|
|
74
|
+
```
|
|
75
|
+
"autoTickets()와 *일관성 있는 코드 작성을 생각한다면, 이렇게 작성하면 더욱 좋을 것* 같아요"
|
|
76
|
+
|
|
77
|
+
### 9. *학생 자가 의문* — 싱글톤 vs 클래스 + 프로퍼티 vs 함수
|
|
78
|
+
|
|
79
|
+
학생: "ranks라는 값을 *이후 결과값 출력에도 사용해야 해서 외부에서 만들고 다시 함수로 넣어 주게 했던 것 같*아요!. *함수로 두지 않은 이유는 함수로 두면 호출 시마다 같은 값을 가진 다른 객체가 생성되기 때문*입니다!. *LotteryResult가 원래 ResultCalculator였어서 싱글톤 객체가 맞다고 생각*했는데 LotteryResult라고 놓고 보면 *각 게임마다 새로이 생성해도 괜찮을 것 같다는 생각이* 듭니다! 아직까지는 *싱글톤 같아 보이는 경우(calculator 등)에는 싱글톤 객체를 생성하고, 그렇지 않은 경우(PurchaseAmount, Receipt처럼 각 시행마다 새로운 객체가 필요할 것 같은 경우)에는 클래스를 생성*하는데 *어떤 경우에 싱글톤을 만들고 어떤 경우에 클래스를 만들어야 할지 스스로 기준이 잘 잡히지 않습니다*ㅠㅠ"
|
|
80
|
+
|
|
81
|
+
리뷰어 답변: "*어떤 부분에 의존성을 부여하거나 하는 것은 결국 하다보면 트레이드 오프의 순간이 옵니다. 이 점은 많은 코드 작성을 하시면서 직접 깨달으셔야 하는 부분*이라, *지금 기준에서 무엇이 정답이다라고 말씀을 드리기 어려울 것* 같습니다. *재사용이 중요할 수도 있고, 생성자로 받을지 함수로 받을지 등 여러 가지 선택의 순간*이 옵니다. *이 방법과 저 방법 사이에 어떤 장단점이 있는지, 왜 그렇게 생각했는지를 주관을 가지고 가셨으면 좋겠*습니다. *당장 어디서는 무엇이 좋더라, 무엇을 써야만 한다에 쫒기다 보면 끝이 없*습니다."
|
|
82
|
+
|
|
83
|
+
리뷰어 *개인 의견 예시* (협력 구조):
|
|
84
|
+
```kotlin
|
|
85
|
+
class WinningLottey {
|
|
86
|
+
// 우승 로또에게 -> 승부 결과를 알려줘 (티켓을 건네주며)
|
|
87
|
+
// 로또 결과에게 -> 결과를 알려줘 (티켓과 우승 번호를 건네주며)
|
|
88
|
+
fun matchBy(tickets: List<Lottery>): LotteryResult {. }
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
val winningLottery: WinningLottery
|
|
92
|
+
val result = winningLottery.matchBy(tickets)
|
|
93
|
+
val profit = result.getProfit(purchase)
|
|
94
|
+
val ranks = result.getRanks()
|
|
95
|
+
```
|
|
96
|
+
"*위 구조는 LotteryResult를 만드는 데 필요한 것을 하나하나 꺼내와서 합치는 방식이 아닌, 필요에 따라 협력하는 구조로 만든 과정*이 됩니다." + *100회 로또 당첨 번호 시나리오* 비교:
|
|
97
|
+
```kotlin
|
|
98
|
+
# 1: 매번 LotteryResult(Ticket, winningLotto) 새로 만듦
|
|
99
|
+
# 2: val results = winningLotto.matchBy(Tickets); results.get(1)
|
|
100
|
+
```
|
|
101
|
+
"*결론은, 설계와 구현은 자유롭다*.."
|
|
102
|
+
|
|
103
|
+
### 10. *`run` 사용 불필요*
|
|
104
|
+
|
|
105
|
+
리뷰어: "*run을 사용한 이점이 없*습니다."
|
|
106
|
+
|
|
107
|
+
## 리뷰어 의견 요지
|
|
108
|
+
|
|
109
|
+
- **`PurchaseAmount` *책임 = 금액*** — 수량은 *Order*.
|
|
110
|
+
- **`Quantity` 양수 invariant 별도**.
|
|
111
|
+
- **자동/수동 *함수명 명시***.
|
|
112
|
+
- **`List(size) { gen() }`**.
|
|
113
|
+
- **오류 *출처 = 처리 책임***.
|
|
114
|
+
- **`LottoResult` *스스로 계산*** — 외부 조립 X.
|
|
115
|
+
- **`val` 우선** (init 결정 시).
|
|
116
|
+
- **일관성 *변수명***.
|
|
117
|
+
- **싱글톤 vs 클래스 *트레이드오프*** — *직접 깨달아야*.
|
|
118
|
+
- **`run` *이점 없으면 X***.
|
|
119
|
+
|
|
120
|
+
- **대표 인용:**
|
|
121
|
+
> 입력을 받는 중에 실패한 것이라면, InputView에서 스스로 출력을 하고 *컨트롤러에서 오류를 확인하는 목적이라면, 컨트롤러에서 콘솔에 출력을 할 수 있고 사용자에게 오류를 전달하고 싶다면, OutputView로 오류를 출력*할 수 있겠습니다.
|
|
122
|
+
> — @laco-dev on `src/main/kotlin/lotto/controller/LottoController.kt`
|
|
123
|
+
|
|
124
|
+
> 어떤 부분에 의존성을 부여하거나 하는 것은 *결국 하다 보면 트레이드 오프의 순간*이 옵니다. 이 점은 *많은 코드 작성을 하시면서 직접 깨달으셔야 하는 부분*이라, 지금 기준에서 무엇이 정답이다라고 말씀을 드리기 어려울 것 같습니다.
|
|
125
|
+
> — @laco-dev (싱글톤 vs 클래스 학생 질문에)
|
|
126
|
+
|
|
127
|
+
> 위 구조는 LotteryResult를 만드는 데 필요한 것을 하나하나 꺼내와서 합치는 방식이 아닌, *필요에 따라 협력하는 구조*로 만든 과정이 됩니다.
|
|
128
|
+
> — @laco-dev on `src/main/kotlin/lotto/domain/WinningLottery.kt`
|
|
129
|
+
|
|
130
|
+
> 결론은, 설계와 구현은 자유롭다.
|
|
131
|
+
> — @laco-dev
|
|
132
|
+
|
|
133
|
+
## 얻은 교훈
|
|
134
|
+
|
|
135
|
+
- **`PurchaseAmount` *금액 책임만*** — *수량/수동/자동*은 *Order* 도메인.
|
|
136
|
+
- **`Quantity` *양수 invariant*** = 원시값 포장 + 검증. *PurchaseAmount.numberOfLottos: Quantity*.
|
|
137
|
+
- **자동/수동 *함수명에 명시*** — `getManualQuantity()`. *암묵 컨텍스트* 의존 회피.
|
|
138
|
+
- **`List(size) { gen() }`** = Kotlin idiom. *모든 PR 공통*.
|
|
139
|
+
- **오류 *출처 = 처리 책임*** — InputView 입력 오류 → InputView, 도메인 생성 → Controller/OutputView. *책임 흐름*.
|
|
140
|
+
- **`LottoResult` *스스로 계산*** — *외부에서 ranks 만들어 다시 넣기*는 *Tell-Don't-Ask 위반*. *생성 시점에 협력자 다 받아*서 *내부 계산*.
|
|
141
|
+
- **`val` 우선** — *init에서 결정*되면 *val*. *재할당 가능성*만 *var*.
|
|
142
|
+
- **일관성 *변수명*** — *대구 (對句)* 가독성.
|
|
143
|
+
- **싱글톤 vs 클래스 = *트레이드오프*** — *재사용 vs 시행별 생성*. *기준은 자기 경험*. 리뷰어가 *정답 제시 거부*는 *PR #75 말리빈*, *PR #137 hyemdooly*와 같은 패턴.
|
|
144
|
+
- **`run`은 *이점 명확할 때*** — *지역 변수 + 명시 호출*이 자연.
|
|
145
|
+
- **`WinningLottery.matchBy(tickets): LottoResult` *협력 구조*** — *값 조립 → 메시지 협력*. *100회 로또 시나리오*가 *재사용성* 강조.
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# PR #59 — [레오] 1단계 로또
|
|
2
|
+
|
|
3
|
+
- **Reviewee:** [@jaeyeongjo](https://github.com/jaeyeongjo)
|
|
4
|
+
- **PR:** https://github.com/woowacourse/kotlin-lotto/pull/59
|
|
5
|
+
- **단계:** 1단계
|
|
6
|
+
- **리뷰어:** @laco-dev
|
|
7
|
+
- **라인 코멘트:** 58
|
|
8
|
+
|
|
9
|
+
## 잘한 점 (설계 관점)
|
|
10
|
+
|
|
11
|
+
- **`Lotto`, `LottoNumber`, `Rank`, `LottoAnalyzer` 분리**.
|
|
12
|
+
|
|
13
|
+
## 못한 점 (설계 관점)
|
|
14
|
+
|
|
15
|
+
### 1. 테스트만 있는 커밋
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
test: LottoTest 생성
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
> 하나의 기능을 작성할 때에는 테스트 코드와 구현 코드가 항상 같이 존재해야 합니다.
|
|
22
|
+
|
|
23
|
+
### 2. `LottoNumber` 주 생성자가 String
|
|
24
|
+
|
|
25
|
+
```kotlin
|
|
26
|
+
class LottoNumber(val value: String) {
|
|
27
|
+
init { require(value.toIntOrNull() in 1..45) }
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
> 로또 번호는 숫자로 이루어져 있으니, 주 생성자로 가지는 값은 Int 타입이어야 하지 않을까요?
|
|
32
|
+
|
|
33
|
+
→ 도메인 객체는 *도메인 타입*. String 파싱은 호출자 (InputView).
|
|
34
|
+
|
|
35
|
+
### 3. Rank 등수 수동 비교에 매직넘버 `5`
|
|
36
|
+
|
|
37
|
+
```kotlin
|
|
38
|
+
if (matchCount == 5 && hasBonus).
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
> `5` 값을 하드코딩 하는 대신에 enum 에 정의된 값을 활용해보세요
|
|
42
|
+
|
|
43
|
+
→ `Rank.SECOND.matchCount`로 간접 참조.
|
|
44
|
+
|
|
45
|
+
### 4. `LottoAnalyzer` god-object
|
|
46
|
+
|
|
47
|
+
```kotlin
|
|
48
|
+
class LottoAnalyzer(lottos: Lottos, winning: WinningLotto) {
|
|
49
|
+
fun rankOf(lotto: Lotto): Rank =.
|
|
50
|
+
fun statistics(): Map<Rank, Int> =.
|
|
51
|
+
fun profitRate(): Double =.
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
> LottoAnalyzer 객체가 협력을 하지 않고 모든 결과를 처리하려고 하기 때문에 상당히 복잡하게 구현되었습니다. 객체가 외부 (LottoAnalyzer)를 통하지 않고 스스로 결과를 만들어 내려면 어떻게 해야 할까요?
|
|
56
|
+
|
|
57
|
+
→ Analyzer가 모든 책임을 가져가면 god-object. 각 도메인이 *자기 책임*.
|
|
58
|
+
|
|
59
|
+
### 5. Rank 테스트 일부만
|
|
60
|
+
|
|
61
|
+
→ 모든 등수 (1~5, MISS) 테스트.
|
|
62
|
+
|
|
63
|
+
## 얻은 교훈
|
|
64
|
+
|
|
65
|
+
- **도메인 객체의 주 생성자 = 도메인 타입**. String 파싱은 *입력 경계*에서 끝.
|
|
66
|
+
- **매직넘버 대신 enum 참조** — enum이 데이터 소유자.
|
|
67
|
+
- **"Analyzer/Calculator/Manager" god-object 패턴** — 모든 결과를 외부 객체가 만들지 말고 각 도메인이 책임.
|
|
68
|
+
- **enum 케이스 전부 테스트** = 비즈니스 분기 전체 검증.
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# PR #83 — [로또] 레오 2단계 미션
|
|
2
|
+
|
|
3
|
+
- **Reviewee:** [@jaeyeongjo](https://github.com/jaeyeongjo)
|
|
4
|
+
- **PR:** https://github.com/woowacourse/kotlin-lotto/pull/83
|
|
5
|
+
- **단계:** 2단계
|
|
6
|
+
- **리뷰어:** @laco-dev
|
|
7
|
+
- **라인 코멘트:** 47
|
|
8
|
+
|
|
9
|
+
## 잘한 점
|
|
10
|
+
|
|
11
|
+
- **`LottoBudget` 도입 — 지갑 비유** (칭찬).
|
|
12
|
+
|
|
13
|
+
## 못한 점 + 핵심 지적
|
|
14
|
+
|
|
15
|
+
### 1. 캡슐화 기능 사라짐
|
|
16
|
+
|
|
17
|
+
```kotlin
|
|
18
|
+
class LottoResult {. } // 일부 메서드가 다시 외부로 노출됨
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
> 이 기능은 캡슐화를 위한 역할을 잘 수행하고 있는데, 왜 다시 사라졌을까요?
|
|
22
|
+
|
|
23
|
+
→ 리팩토링 중 캡슐화 약화 발생. *변경 의도*가 명확해야.
|
|
24
|
+
|
|
25
|
+
### 2. 수동 + 자동 패턴 불일치
|
|
26
|
+
|
|
27
|
+
```kotlin
|
|
28
|
+
val autoLottos = AutoLottoMachine.create(budget, generator)
|
|
29
|
+
val manualLottos = ManualLottoMachine(numbers).get() // ⚠ 다른 사용 패턴
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
> 수동 로또와 자동 로또의 발급 패턴이 유사한 것 같은데, 사용하는 방법이 다르게 사용되고 있네요. 번호들을 발급한다는 협력에 집중해서 본다면 단순하게 만들어 볼 수 있지 않을까요?
|
|
33
|
+
> ```kotlin
|
|
34
|
+
> AutoLotoMachine.createLottos(budget, RandomLottoNumbersGenerator())
|
|
35
|
+
> ```
|
|
36
|
+
|
|
37
|
+
### 3. 지갑 차감 — 발급 실패 시 일관성?
|
|
38
|
+
|
|
39
|
+
```kotlin
|
|
40
|
+
class LottoBudget(.) {
|
|
41
|
+
fun deduct(amount: Int) {. } // ⚠ 차감 후 발급 실패하면?
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
> LottoBudget을 만들어주셔서 지갑처럼 사용되는 설계 방법 좋았습니다. 다만 지갑을 먼저 차감하기 때문에 실제 로또를 발급하는 과정에서 문제가 생긴다면 어떻게 될까요? 상태를 만들어서 관리를 하는 방법도 좋지만, 단순히 생성할 갯수만 입력받는 방법이라면 위 문제는 사라집니다.
|
|
46
|
+
|
|
47
|
+
→ 트랜잭션 무결성 의식. 또는 *수량 계산만* 받고 *지갑 보유*는 외부.
|
|
48
|
+
|
|
49
|
+
## 얻은 교훈
|
|
50
|
+
|
|
51
|
+
- **리팩토링 중 캡슐화 약화** = 변경 의도 검토 필요.
|
|
52
|
+
- **수동/자동 패턴 통일** — 같은 *발급 협력*이면 같은 시그니처.
|
|
53
|
+
- **상태 보유의 트랜잭션 부담** — 차감 후 실패 시 롤백 어려움. *수량만 받는* 무상태 함수가 더 안전.
|