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,126 @@
|
|
|
1
|
+
# PR #140 — [비비] 2단계 로또
|
|
2
|
+
|
|
3
|
+
- **Reviewee:** [@rosemin928](https://github.com/rosemin928)
|
|
4
|
+
- **PR:** https://github.com/woowacourse/kotlin-lotto/pull/140
|
|
5
|
+
- **단계:** 2단계 (수동 로또)
|
|
6
|
+
- **리뷰어:** @Gyuil-Hwnag (규일)
|
|
7
|
+
- **라인 코멘트:** 30 (리뷰어 19 + 학생 11)
|
|
8
|
+
|
|
9
|
+
## 잘한 점 (설계 관점)
|
|
10
|
+
|
|
11
|
+
- **`LottoGenerator` 활용** — 칭찬: "*Generator를 통한 생성 정말 좋습니다*ㅎㅎ👍".
|
|
12
|
+
- **`Profit` 테스트 정밀** — 칭찬: "*Profit에 대한 테스트 정말 좋습니다*ㅎㅎ👍 *어떤 것이 주어졌고, 어떤 것을 테스트하며, 결과는 어떤 것인지 한눈에 들어오는군요*~".
|
|
13
|
+
- **`LottoStore` 도입 → 테스트 가능** — 칭찬: "*LottoStore가 생겨남으로써, LottoStore를 통해서 로또 생성에 대한 테스트가 가능*해졌군요~💯".
|
|
14
|
+
- **2단계 README 분리 작성** — 칭찬: "2단계 요구사항에 대한 *README 작성 좋습니다*~👍".
|
|
15
|
+
- **당첨 로직 테스트 작성** — 칭찬: "*당첨 로직에 대한 테스트 코드 작성 정말 좋습니다*~👍".
|
|
16
|
+
|
|
17
|
+
## 못한 점 (설계 관점)
|
|
18
|
+
|
|
19
|
+
### 1. *자동/수동 변수명 모호*
|
|
20
|
+
|
|
21
|
+
```kotlin
|
|
22
|
+
val lottos =. // ⚠ 자동인가 수동인가
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
리뷰어: "*자동 로또와 수동 로또를 구분해 주셨군요*~ *자동 로또라는 네이밍이 드러나게 변수명을 지어봐도 좋을 것 같*다는 생각이 듭니다!" — `autoLottos`, `manualLottos`.
|
|
26
|
+
|
|
27
|
+
### 2. *순서가 바뀜*
|
|
28
|
+
|
|
29
|
+
리뷰어: "*순서가 바뀐 것* 같아요~"
|
|
30
|
+
|
|
31
|
+
### 3. `LottoTicketCounter.count(): List<Int>` — 두 값 합치기
|
|
32
|
+
|
|
33
|
+
```kotlin
|
|
34
|
+
class LottoTicketCounter {
|
|
35
|
+
fun count(): List<Int> = listOf(manualCount, autoCount) // ⚠ 두 의미 합침
|
|
36
|
+
}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
리뷰어: "*해당값을 리스트로 만들어야 할 이유가 있을까? 라는 생각이 듭니다*! *fun manualCount(), fun autoCount() 이렇게 두 개로 나눠보는 것은 어떨까* 라는 생각이 듭니다~" — *List에 두 다른 의미*가 들어가면 *index access*가 *의미 모호*.
|
|
40
|
+
|
|
41
|
+
### 4. *`numbers[0], numbers[1]` 위치 의존*
|
|
42
|
+
|
|
43
|
+
리뷰어: "*numbers[0], numbers[1]라고 받은 부분이 살짝 고민이* 되긴 합니다! *현재의 구조를 모르는 사람이 본다면 해당 구현을 보고 어떤 건지 단번에 파악이 가능할까? 라는 생각*이 듭니다~ *autoCount, manualCount로 확실하게 구분을 지어서 파라미터로 받는 방법도 좋을 것 같다*는 생각이 듭니다💪"
|
|
44
|
+
|
|
45
|
+
### 5. `LottoTicketCounter` *존재 정당화* — 학생 자가 의문
|
|
46
|
+
|
|
47
|
+
학생: "*LottoTicketCounter는 로또 개수를 세는 역할, LottoStore는 로또를 발행하는 역할이라고 생각해서 따로 두었는데 이를 합치면 더 좋을까요*.?"
|
|
48
|
+
|
|
49
|
+
리뷰어: "말씀해 주신 대로, *LottoStore에서 Count 하나로 묶는 방법도 있을 것 같긴 한데, 구조상 그렇게 변경하기가 쉽지 않아 보이긴 하네요*! *LottoTicketCounter라는 객체가 굳이 필요할까? 라는 의문이 듭니다*! *현재 역할은 Auto, Manual 갯수를 계산하는 역할에 지나지 않는다*는 생각이 듭니다🤔"
|
|
50
|
+
|
|
51
|
+
후속: "*LottoTicketCount가 있어도 괜찮다고 생각을 하신 건 현재 로직을 담고 있기 때문인가 보군요*!👍 아주 좋습니다ㅎㅎ 그렇다면 *담당하는 역할은 아래와 같은데 LottoTicketCounter이라는 네이밍이 비비가 보시기에는 어떠신가요*??🤔 *로또의 구매할 수 있는 최저 금액 & 내가 구매한 로또 갯수 & 내가 구매한 자동 로또의 갯수*" — *책임 = 네이밍*이 *일치*해야.
|
|
52
|
+
|
|
53
|
+
### 6. *수동 로또 입력 실패 시 전체 재입력?* — UX
|
|
54
|
+
|
|
55
|
+
학생: *로또 10장 입력 도중 1번째 잘못되면 모두 다시 입력?*
|
|
56
|
+
|
|
57
|
+
리뷰어: "*오호~ 아주 좋은 고민을 하셨군요*!👍 *로또를 열심히 10장을 적었는데, 사실 1번째 줄이 잘못되었다고 입력한 모든 것을 다시 입력해야 한다*? 억지스럽긴 한데, *회원가입이라고 한다면 힘들게 10단계를 넘었는데 사실 1단계에서 틀렸으니 다시 힘들게 10단계를 입력해야 한다?* *실제 사용자 입장에서는 무척 화가 나는 상황이겠군요*" — *현실 UX 시나리오*로 *입력 단위 검증*의 가치.
|
|
58
|
+
|
|
59
|
+
### 7. *LottoStore 제거 이유*
|
|
60
|
+
|
|
61
|
+
리뷰어: "*LottoStore를 제거하게 된 이유가 궁급*합니다!🤔" — *책임 객체 폐기*의 정당화 필요.
|
|
62
|
+
|
|
63
|
+
### 8. 수동 로또 *발행 테스트 부재*
|
|
64
|
+
|
|
65
|
+
리뷰어: "수동 로또라는 것이 생겼으니, *수동 로또도 제대로 발행을 하는지 한번 테스트해 봐도 좋을 것* 같다는 생각이 듭니다!💪"
|
|
66
|
+
|
|
67
|
+
### 9. *45 이상 입력 → 앱 죽음*
|
|
68
|
+
|
|
69
|
+
리뷰어: "*45 이상의 숫자를 입력하면 앱이 죽도록 되어 있군요*~ 이 부분은 *요구사항에 없긴 한데, 한 번 고민해 보면 좋을 것 같*은 내용인 것 같아서 코멘트 남겨 두었습니다! *재입력을 받도록 해 볼 수도 있겠다는 생각도 드는군요*!💪 (수정이 이루어져야 하는 것은 아니고 *어떻게 하면 해당 기능을 구현할 수 있을지 비비의 의견을 남겨* 주셔도 좋을 것 같습니다)"
|
|
70
|
+
|
|
71
|
+
### 10. 테스트 *공통 부분 상수화*
|
|
72
|
+
|
|
73
|
+
리뷰어: "*테스트 코드 작성 너무 잘해 주셨네요*~👍 *공통으로 테스트에서 이용할 수 있는 부분들에 대해서는 상수화를 해서 관리한다면, 테스트 코드에서 재사용을 하면서 중복된 부분들을 줄여볼 수* 있겠군요!"
|
|
74
|
+
|
|
75
|
+
### 11. 테스트 *컨벤션 일관성*
|
|
76
|
+
|
|
77
|
+
리뷰어: "*테스트 코드 컨벤션이 이러한 방식으로 정해졌다면 일관성 있게 다른 테스트에도 반영을 해 보는 것이 추후 다른 사람이 보더라도 일관되게 보여 한눈에 잘 들어올 수 있겠다*는 생각이 듭니다!" — *Profit 테스트 컨벤션*을 *다른 테스트에 일관 적용*.
|
|
78
|
+
|
|
79
|
+
### 12. *수동 로또 갯수 테스트 다양한 케이스*
|
|
80
|
+
|
|
81
|
+
리뷰어: "*수동 로또를 생성하는 것을 테스트하므로, 여러 가지 실패 등 케이스를 테스트해 봐도 좋겠다*는 생각이 듭니다💪 https://developer.android.com/studio/test/test-in-android-studio#view_test_coverage *테스트 커버리지*라는 개념.". 자료.
|
|
82
|
+
|
|
83
|
+
### 13. *LottoStore 내 로직 vs Profit 분리* — 메타-질문
|
|
84
|
+
|
|
85
|
+
리뷰어: "*해당 로직이 LottoStore 내에 있도록 한다면, 어떤 장점과 단점이 있게 될까요? 수정이 필요한 것은 아니고 비비의 의견을 알려* 주세요~💪"
|
|
86
|
+
|
|
87
|
+
## 리뷰어 의견 요지
|
|
88
|
+
|
|
89
|
+
- **자동/수동 *변수명 명시***.
|
|
90
|
+
- **`List<Int>`에 *두 다른 의미* X**.
|
|
91
|
+
- **`numbers[0], numbers[1]` *index access*는 *모호***.
|
|
92
|
+
- **`LottoTicketCounter` *역할 + 네이밍 일치* 또는 통합**.
|
|
93
|
+
- ***입력 단위 검증* vs 전체 재입력 UX**.
|
|
94
|
+
- **`LottoStore` 제거 *정당화*** 필요.
|
|
95
|
+
- **수동 로또 *발행 테스트***.
|
|
96
|
+
- **45 이상 *앱 죽음* — 재입력 가능성**.
|
|
97
|
+
- **테스트 *공통 상수* + *컨벤션 일관성***.
|
|
98
|
+
- **`Store 내 로직` *책임 분리* 의견**.
|
|
99
|
+
|
|
100
|
+
- **대표 인용:**
|
|
101
|
+
> 로또를 열심히 10장을 적었는데, 사실 1번째 줄이 잘못되었다고 *입력한 모든 것을 다시 입력해야 한다*? 억지스럽긴 한데, 회원가입이라고 한다면 *힘들게 10단계를 넘었는데 사실 1단계에서 틀렸으니 다시 힘들게 10단계를 입력해야 한다*?
|
|
102
|
+
> — @Gyuil-Hwnag on `src/main/kotlin/lotto/view/InputView.kt`
|
|
103
|
+
|
|
104
|
+
> LottoTicketCounter라는 *객체가 굳이 필요할까? 라는 의문*이 듭니다!
|
|
105
|
+
> — @Gyuil-Hwnag on `src/main/kotlin/lotto/domain/LottoTicketCounter.kt`
|
|
106
|
+
|
|
107
|
+
> 해당값을 *리스트로 만들어야 할 이유*가 있을까? fun manualCount(), fun autoCount() 이렇게 *두 개로 나눠 보는 것*은 어떨까.
|
|
108
|
+
> — @Gyuil-Hwnag on `src/main/kotlin/lotto/domain/LottoTicketCounter.kt`
|
|
109
|
+
|
|
110
|
+
> 45 이상의 숫자를 입력하면 *앱이 죽도록 되어 있군요*~
|
|
111
|
+
> — @Gyuil-Hwnag on `src/main/kotlin/lotto/domain/LottoNumber.kt`
|
|
112
|
+
|
|
113
|
+
## 얻은 교훈
|
|
114
|
+
|
|
115
|
+
- **자동/수동 *변수명 = 명시 어휘*** — `autoLottos`, `manualLottos`. *컨텍스트 의존*은 *모호*.
|
|
116
|
+
- **`List<Int>`에 *두 다른 의미*가 들어가면 *index access*가 *의미 모호*** — `fun manualCount()`, `fun autoCount()` 분리.
|
|
117
|
+
- **`numbers[0], numbers[1]` *위치 의존*** — 새 멤버는 *의미 자동 파악 불가*. *명시 파라미터*가 안전.
|
|
118
|
+
- **`LottoTicketCounter` *역할 + 네이밍 일치*** — *Auto/Manual 개수 + 최저 금액 + 자동 갯수*가 *책임이라면*, *Counter*는 *책임 일부만* 반영. *네이밍 재검토 또는 통합*.
|
|
119
|
+
- ***입력 단위 검증 = UX*** — *10장 중 1번째 오류 시 전체 재입력*은 *최악 UX*. *회원가입 10단계* 비유 강력. *각 줄 단위 재입력*이 자연.
|
|
120
|
+
- **`LottoStore` 제거 *정당화 필요*** — *책임 객체 폐기*는 *왜 폐기인지* 설명. *역할이 흩어졌는지 통합되었는지*.
|
|
121
|
+
- **수동 발행 테스트** = *새 기능에 새 테스트*. *기존 테스트만으로 부족*.
|
|
122
|
+
- **45 이상 *앱 죽음* = 요구사항 외 UX 고려** — *재입력*이 *현실*.
|
|
123
|
+
- **테스트 *공통 상수***. *fixture object*와 같은 *중복 제거 + 의미 명시*.
|
|
124
|
+
- **테스트 *컨벤션 일관성*** — 한 테스트가 *given/when/result* 양호하면, *다른 테스트도 동일 형식*. PR #61 (Junyoung-WON) Rank 부분 테스트와 같은 결.
|
|
125
|
+
- **`LottoStore 내 로직`** — *책임 응집 vs 분리* 트레이드오프. *현실 도메인 (가게)*가 *얼마나 많은 일*을 하는가.
|
|
126
|
+
- **회원가입 *10단계 1단계 오류 비유*** — *UX 시나리오*는 *코드 결정*의 강력한 근거.
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
# PR #103 — [로또] 빙티 2단계 미션
|
|
2
|
+
|
|
3
|
+
- **Reviewee:** [@s6m1n](https://github.com/s6m1n)
|
|
4
|
+
- **PR:** https://github.com/woowacourse/kotlin-lotto/pull/103
|
|
5
|
+
- **단계:** 2단계 (수동 로또 추가)
|
|
6
|
+
- **리뷰어:** @laco-dev (페로로)
|
|
7
|
+
- **라인 코멘트:** 23
|
|
8
|
+
|
|
9
|
+
## 잘한 점 (설계 관점)
|
|
10
|
+
|
|
11
|
+
- **`LottoTickets` 일급 컬렉션** — `concat` 행위.
|
|
12
|
+
- **`Money.calculateQuantity(LOTTO_PRICE)`** — 도메인 객체에 책임 위임.
|
|
13
|
+
- **`Cashier` 객체 제거 + Money로 책임 통합** — 1단계 리뷰 반영.
|
|
14
|
+
- **자가 의문 PR에 풍부히 명시** — *수동 Generator의 존재 의미*, *Generator 추상화 수준 통일* 등.
|
|
15
|
+
|
|
16
|
+
## 못한 점 (설계 관점)
|
|
17
|
+
|
|
18
|
+
### 1. 수동 발행 위치 — 학생 자가 의문
|
|
19
|
+
|
|
20
|
+
학생 분석: "자동의 경우 LottoGenerator를 상속하는 RandomLottoGenerator에서 만들어지고 있습니다. 그러나 수동의 경우 별도의 Generator를 거치지 않고 컨트롤러에서 사용자로부터 값을 입력받아 바로 Lotto 객체로 만들어 줍니다. *같은 지위를 가지는 객체들인 만큼 생성 과정에 있어서 추상화 수준을 동일시*해야 하지 않을까?라는 의문." 학생 시도 후 결론: "수동 로또 generator을 추가하는 시도 끝에 [수정 전 구조]가 더 낫다는 결론." 리뷰어: "단순히 협력하는 구조가 되는 방식이 아쉬웠다면, 확장성을 위해 한 번 더 협력을 하도록 만들 수도 있습니다. *참고만*: `ManualLottoMachine { InputView.getLottoNumbers().toLottoNumbers() }`."
|
|
21
|
+
|
|
22
|
+
### 2. `getTotalLottoTicket`이 *조회 + 출력*
|
|
23
|
+
|
|
24
|
+
```kotlin
|
|
25
|
+
private fun getTotalLottoTicket(manualLottoTickets, autoLottoTickets): LottoTickets {
|
|
26
|
+
OutputView.printLottoQuantity(.)
|
|
27
|
+
val totalLottoTickets = manualLottoTickets.concat(autoLottoTickets)
|
|
28
|
+
OutputView.printLottoNumbers(totalLottoTickets.tickets)
|
|
29
|
+
return totalLottoTickets
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
리뷰어: "TotalLottoTicket을 가져온다는 행위가, *출력을 같이 하고 있다면* 두 가지 역할을 하고 있다고 볼 수 있지 않을까요? 가령 정말로 로또 티켓을 가져오려고 호출했는데, *그때마다 콘솔에 찍히게 됩니다*." — `get*` 메서드는 *순수 반환*만.
|
|
34
|
+
|
|
35
|
+
### 3. 상수 중복 — `LottoController`와 `LottoNumber`
|
|
36
|
+
|
|
37
|
+
```kotlin
|
|
38
|
+
companion object {
|
|
39
|
+
const val LOTTO_PRICE = 1000
|
|
40
|
+
const val MINIMUM_LOTTO_NUMBER = 1 // ⚠ LottoNumber도 보유
|
|
41
|
+
const val MAXIMUM_LOTTO_NUMBER = 45
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
리뷰어: "LottoNumber와 이곳 중복으로 상수를 사용한다면, *두 개 모두 바꾸어야 한다는 사실*을 개발자가 놓치기 쉽지 않을까요?"
|
|
46
|
+
|
|
47
|
+
### 4. 수익률 책임 위치 — `Money.calculateRate` vs `LottoDrawingResult`
|
|
48
|
+
|
|
49
|
+
```kotlin
|
|
50
|
+
val marginRate = purchaseMoney.calculateRate(result.calculateTotalPrize())
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
리뷰어: "수익률이라는 것은 Money가 만들어 내는 것과 LottoDrawingResult가 만들어 내는 것 무엇이 더 적절하다고 생각하시나요? 만약 로또 게임에서 만들어야 하는 결과에 *다른 값*이 생긴다면 어떻게 될까요?" 학생: "수익률이 Money를 기반으로 계산되어서 calculateRate를 Money 클래스 내부에 두었는데, *다른 값이라는 확장*을 염두에 두면 *새로운 값과 수익률 모두 LottoDrawingResult에서 관리*하는 것이 통일성 있다고 생각합니다."
|
|
54
|
+
|
|
55
|
+
### 5. `LottoDrawingResult.resultStatistics` 직접 노출
|
|
56
|
+
|
|
57
|
+
```kotlin
|
|
58
|
+
val resultStatistics: Map<Rank, Int> =.
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
리뷰어: "`resultStatistics`가 그대로 외부로 노출되어 있다면, 값에 해당하는 Int 타입이 무엇을 의미하는 것인지 알 수 있을까요? 갯수일 수도 있고, 가격의 총 합일지도 모릅니다. 이러한 경우 명확하게 메시지를 만들어 의도를 전달할 수 있습니다. `fun getWinningCountByRank(rank: Rank): Int {. }`." 학생: "예시로 들어 주신 getWinningCountByRank에서 힌트를 얻어 코드를 수정해 봤습니다! resultStatistics도 삭제되고, getWinningCountByRank라는 네이밍 덕분에 count라는 걸 개발자가 직관적으로 알 수 있겠네요."
|
|
62
|
+
|
|
63
|
+
### 6. `coerceAtMost`/`coerceIn` 학습 시드
|
|
64
|
+
|
|
65
|
+
```kotlin
|
|
66
|
+
fun readPurchaseQuantity(maxQuantity: Int): Int {
|
|
67
|
+
val input = readln().toInt()
|
|
68
|
+
return if (input !in 0..maxQuantity) maxQuantity else input
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
리뷰어: "`Int.coerceAtXXX(.)`라는 함수가 있어요 한번 찾아보세요." — Kotlin 표준 라이브러리의 *범위 클램프*.
|
|
73
|
+
|
|
74
|
+
### 7. 테스트 함수명에 *구현 메서드명* 노출
|
|
75
|
+
|
|
76
|
+
```kotlin
|
|
77
|
+
fun `concat으로 두 LottoTickets을 하나의 LottoTickets로 합칠 수 있다`() {. }
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
리뷰어: "함수 이름을 테스트 코드에 그대로 드러내는 건 좋지 않아요. 만약 함수 이름이 변경된다면 테스트 코드도 같이 변경해야 한다는 사실을 *쉽게 놓칠* 수 있으니까요."
|
|
81
|
+
|
|
82
|
+
### 8. README에 변수 잔존
|
|
83
|
+
|
|
84
|
+
```
|
|
85
|
+
"수동 로또 개수는 ${MINIMUM_PURCHASE_AMOUNT}개 이상."
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
리뷰어: "리드미에 변수가 😱" — 카피 시 *템플릿 변수 미해소*는 흔한 실수.
|
|
89
|
+
|
|
90
|
+
## 리뷰어 의견 요지
|
|
91
|
+
|
|
92
|
+
- **`get*` = *반환만***, 출력 등 사이드이펙트 X.
|
|
93
|
+
- **상수 중복 = 변경 함정** — *한 곳* 소유 + import.
|
|
94
|
+
- **수익률은 *결과 객체*의 책임** — 다른 값 확장 시 *통일성*.
|
|
95
|
+
- **외부 노출 Map = *의미 모호*** — `getCount*` 같이 *의미 부여 메서드*.
|
|
96
|
+
- **`coerceIn`/`coerceAtMost` 표준** — 범위 클램프.
|
|
97
|
+
- **테스트 함수명 = 의도, 구현 메서드명 X**.
|
|
98
|
+
- **수동 vs 자동 = *추상화 수준 통일*** 또는 *현실 비유 따라가기* — 정답 없음, 트레이드오프.
|
|
99
|
+
|
|
100
|
+
- **대표 인용:**
|
|
101
|
+
> TotalLottoTicket을 가져온다는 행위가, 출력을 같이 하고 있다면 두 가지 역할을 하고 있다고 볼 수 있지 않을까요?
|
|
102
|
+
> — @laco-dev on `src/main/kotlin/lotto/controller/LottoController.kt`
|
|
103
|
+
|
|
104
|
+
> `resultStatistics`가 그대로 외부로 노출되어 있다면, 값에 해당하는 Int 타입이 무엇을 의미하는 것인지 알 수 있을까요? 갯수일 수도 있고, 가격의 총 합일지도 모릅니다.
|
|
105
|
+
> — @laco-dev on `src/main/kotlin/lotto/domain/model/LottoDrawingResult.kt`
|
|
106
|
+
|
|
107
|
+
> 함수 이름을 테스트 코드에 그대로 드러내는 건 좋지 않아요. 만약 함수 이름이 변경된다면 테스트 코드도 같이 변경해야 한다는 사실을 쉽게 놓칠 수 있으니까요.
|
|
108
|
+
> — @laco-dev on `src/test/kotlin/lotto/domain/model/LottoTicketsTest.kt`
|
|
109
|
+
|
|
110
|
+
## 얻은 교훈
|
|
111
|
+
|
|
112
|
+
- **`get*` 시그니처 = *순수 반환***. 출력/저장 같은 사이드이펙트는 별도 메서드.
|
|
113
|
+
- **상수의 *한 곳* 소유** — 중복 선언은 *한쪽만 바뀌어도 안 깨짐*이라는 *위험한 invariant*.
|
|
114
|
+
- **결과 객체에 *통일된 책임*** — 수익률을 Money에 두면 *다른 결과*가 생길 때 *어디로 가는가* 매번 결정.
|
|
115
|
+
- **`Map<X, Y>` 외부 노출 회피** — 호출자에게 *Y의 의미*가 모호. `getCountByRank` 같이 *의미 부여 메서드*.
|
|
116
|
+
- **Kotlin 표준 *범위 클램프*** — `coerceIn(0, max)`, `coerceAtMost(max)`. 직접 `if-else`보다 의도 명시.
|
|
117
|
+
- **테스트 함수명 = *의도 명세***, 구현 메서드명을 함수명에 두면 *리네임이 테스트 깨짐*.
|
|
118
|
+
- **수동 generator의 *추상화 가치*는 *옵션***. 정답이 아니라 *확장 옵션*. 현재 비용이 가치를 넘으면 *직접 변환*도 OK.
|
|
119
|
+
- **README도 *코드*** — 템플릿 변수 잔존 등은 *리뷰 책임*.
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# PR #66 — [로또] 빙티 1단계 미션
|
|
2
|
+
|
|
3
|
+
- **Reviewee:** [@s6m1n](https://github.com/s6m1n) (페어 진행)
|
|
4
|
+
- **PR:** https://github.com/woowacourse/kotlin-lotto/pull/66
|
|
5
|
+
- **단계:** 1단계
|
|
6
|
+
- **리뷰어:** @laco-dev
|
|
7
|
+
- **라인 코멘트:** 60
|
|
8
|
+
|
|
9
|
+
## 잘한 점 (설계 관점)
|
|
10
|
+
|
|
11
|
+
- **`LottoNumber`, `Money`, `Rank`, `WinningLotto`, `LottoController` 분리**.
|
|
12
|
+
- **`Money.ZERO` 같은 도메인 상수 시도**.
|
|
13
|
+
- **`MethodSource` 테스트**.
|
|
14
|
+
|
|
15
|
+
## 못한 점 (설계 관점)
|
|
16
|
+
|
|
17
|
+
### 1. 커밋 단위 — 테스트만 (구현 없음)
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
test(LottoNumberTest): LottoNumber 생성 테스트 추가
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
> TDD로 구현하는 것은, 테스트를 먼저 작성해서 커밋을 올리는 것이 아닌 테스트를 선행하여 더 좋은 구조의 설계를 지향하는 과정입니다. 그렇기 때문에 하나의 기능 단위(커밋)에서는 구현 코드와 테스트 코드가 동시에 존재해야만 합니다.
|
|
24
|
+
|
|
25
|
+
→ TDD = *사고 흐름*이지 *커밋 분리*가 아님.
|
|
26
|
+
|
|
27
|
+
### 2. 패키지 구조 — lotto 안에 모이지 않음
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
controller/
|
|
31
|
+
domain/model/
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
→ `lotto` 패키지 아래로 모아 다른 미션과 분리.
|
|
35
|
+
|
|
36
|
+
### 3. `Money.ZERO`가 Int 반환
|
|
37
|
+
|
|
38
|
+
```kotlin
|
|
39
|
+
class Money(val value: Int) {
|
|
40
|
+
companion object {
|
|
41
|
+
const val ZERO = 0 // ⚠ Int 반환
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
> `Money.ZERO`가 Int 타입을 반환하는게 맞을까요? `Money(0) == Money.ZERO` 를 비교하는게 더 일반적이지 않을까요?
|
|
47
|
+
|
|
48
|
+
→ `Money.ZERO`는 Money 타입이어야 동등성/사칙연산 자연스러움.
|
|
49
|
+
|
|
50
|
+
### 4. `receiveMoney()` 반환 타입 `Pair<Money, Int>`
|
|
51
|
+
|
|
52
|
+
```kotlin
|
|
53
|
+
fun receiveMoney(): Pair<Money, Int> {. }
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
> receiveMoney() 함수가 반환하는 `Pair<Money, Int>` 타입이 무엇인지 의미가 충분히 드러나고 있을까요?
|
|
57
|
+
|
|
58
|
+
→ Money + 무엇? data class로 의미 부여.
|
|
59
|
+
|
|
60
|
+
### 5. 에러 메시지 상수의 위치 자가 의문
|
|
61
|
+
|
|
62
|
+
학생 의문:
|
|
63
|
+
|
|
64
|
+
> 테스트를 위해 에러 메시지 상수를 Constants에 둘 지, 테스트 할 클래스 내부의 companion object에 public const val로 둘 지 고민했습니다. 후자는 테스트에서 클래스를 의존해서 안 좋다고 생각하는데.
|
|
65
|
+
|
|
66
|
+
리뷰어 답:
|
|
67
|
+
|
|
68
|
+
> 기능을 테스트 할 때에.
|
|
69
|
+
|
|
70
|
+
→ 테스트가 클래스의 *공개 상수*에 의존하는 건 OK. 동작이 *그 메시지를 던지는지* 검증.
|
|
71
|
+
|
|
72
|
+
### 6. `MethodSource` 의도 불명
|
|
73
|
+
|
|
74
|
+
```kotlin
|
|
75
|
+
@MethodSource("rankProvider")
|
|
76
|
+
@ParameterizedTest
|
|
77
|
+
fun `Rank 매칭`(matchCount: Int, bonus: Boolean, expected: Rank) {. }
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
> 하지만 이 테스트가 어떤 의도를 가지고 어떤 결과를 기대하는지 전달하기에는 충분하지 못할 때가 많습니다. MethodSource에서의 파라미터가 무엇인지 확인하기 위해 일일히 찾아가서 확인해야 하고
|
|
81
|
+
|
|
82
|
+
→ MethodSource는 *케이스 수가 많을 때*만. 적으면 inline + 명시적 이름.
|
|
83
|
+
|
|
84
|
+
### 7. `assertThrows` 파라미터 미확인
|
|
85
|
+
|
|
86
|
+
```kotlin
|
|
87
|
+
assertThrows<IllegalArgumentException> {. }
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
> assertThrows() 함수의 파라미터로 무엇을 전달하는지 확인해보세요.
|
|
91
|
+
|
|
92
|
+
→ 메시지/원인까지 확인하면 검증 강도 ↑.
|
|
93
|
+
|
|
94
|
+
## 리뷰어 의견 요지
|
|
95
|
+
|
|
96
|
+
리뷰어 @laco-dev의 가르침:
|
|
97
|
+
|
|
98
|
+
1. **TDD 커밋 단위 = 완결된 기능 (테스트 + 구현)**.
|
|
99
|
+
|
|
100
|
+
2. **값 객체의 동등성 = 같은 타입 비교**. `Money.ZERO`는 Money 타입.
|
|
101
|
+
|
|
102
|
+
3. **Pair는 일회용**. 영구한 자료는 data class.
|
|
103
|
+
|
|
104
|
+
4. **테스트가 *공개 상수*에 의존하는 건 OK** — 동작의 일부.
|
|
105
|
+
|
|
106
|
+
5. **`MethodSource` 가독성 trade-off** — 케이스 수에 따라.
|
|
107
|
+
|
|
108
|
+
- **대표 인용:**
|
|
109
|
+
> `Money.ZERO`가 Int 타입을 반환하는게 맞을까요? `Money(0) == Money.ZERO` 를 비교하는게 더 일반적이지 않을까요?
|
|
110
|
+
>
|
|
111
|
+
> — @laco-dev on `src/main/kotlin/domain/model/Money.kt`
|
|
112
|
+
|
|
113
|
+
## 얻은 교훈
|
|
114
|
+
|
|
115
|
+
- **값 객체의 상수 = 같은 값 객체 타입**. `Money.ZERO: Money`. `Money.ZERO: Int`면 wrapping 의미 약화.
|
|
116
|
+
- **`Pair<T, U>` 반환 = 의미 잃은 자리**. data class로 두 필드에 이름 부여.
|
|
117
|
+
- **TDD 커밋 = 사고 흐름의 결과지 *커밋 단위*가 아니다**. test/feat 분리는 *과정 기록*.
|
|
118
|
+
- **`MethodSource` 사용 기준** = 케이스 수 ≥ 10개 정도. 적으면 `@CsvSource` 또는 inline.
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# PR #18 — [산군] 1단계 로또
|
|
2
|
+
|
|
3
|
+
- **Reviewee:** [@s9hn](https://github.com/s9hn)
|
|
4
|
+
- **PR:** https://github.com/woowacourse/kotlin-lotto/pull/18
|
|
5
|
+
- **단계:** 1단계
|
|
6
|
+
- **리뷰어:** @namjackson
|
|
7
|
+
- **라인 코멘트:** 63
|
|
8
|
+
|
|
9
|
+
## 잘한 점 (설계 관점)
|
|
10
|
+
|
|
11
|
+
- **`BonusNumber`, `Lotto`, `Count`, `ShuffledNumberGenerator` 분리**.
|
|
12
|
+
- **`Rank` enum + countOfMatch**.
|
|
13
|
+
|
|
14
|
+
## 못한 점 (설계 관점)
|
|
15
|
+
|
|
16
|
+
### 1. `LottoController.printLottoResult` — 함수명과 책임 불일치
|
|
17
|
+
|
|
18
|
+
```kotlin
|
|
19
|
+
private fun printLottoResult(lottos: List<Lotto>, winning:.) {
|
|
20
|
+
val rank =.calculate.
|
|
21
|
+
val profit =.calculate.
|
|
22
|
+
println(rank)
|
|
23
|
+
println(profit)
|
|
24
|
+
}
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
> printLottoResult라는 함수이름이지만, 내부적으로는 많은 일을 하는 것 같아요!
|
|
28
|
+
|
|
29
|
+
→ 계산 + 출력 둘 다. *print*은 출력만, *계산은 도메인*.
|
|
30
|
+
|
|
31
|
+
### 2. 컬렉션 API 미활용 (forEach 대신 for문)
|
|
32
|
+
|
|
33
|
+
→ map/filter/forEach가 의도 명시적.
|
|
34
|
+
|
|
35
|
+
### 3. `Count` 값 객체를 만들었지만 Int로 반환
|
|
36
|
+
|
|
37
|
+
```kotlin
|
|
38
|
+
fun numberOfLottos(): Int =. // ⚠ Count 만들었는데 Int 반환
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
> int가 아닌, Count 그대로 반환하면 어떨까요?
|
|
42
|
+
|
|
43
|
+
→ 값 객체 만든 의미 = 호출처도 그 객체로 다루기.
|
|
44
|
+
|
|
45
|
+
### 4. Rank 2등/3등 같은 countOfMatch (5개)
|
|
46
|
+
|
|
47
|
+
```kotlin
|
|
48
|
+
enum class Rank(val countOfMatch: Int, val money: Int) {
|
|
49
|
+
SECOND(5, 30_000_000),
|
|
50
|
+
THIRD(5, 1_500_000), // ⚠ 같은 countOfMatch
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
> 2등과 3등의 countOfMatch가 일치하네요, Rank에서 2등과 3등을 어떻게 분리를 할수 있을까요? Bonus볼의 여부도 Rank의 책임이 아닐까요?
|
|
55
|
+
|
|
56
|
+
→ Rank가 matchBonus를 *판별 데이터*로 가지면 명확.
|
|
57
|
+
|
|
58
|
+
### 5. `BonusNumber`에 getter/setter
|
|
59
|
+
|
|
60
|
+
```kotlin
|
|
61
|
+
class BonusNumber {
|
|
62
|
+
private var number: Int = 0
|
|
63
|
+
fun getNumber(): Int = number
|
|
64
|
+
fun setNumber(v: Int) { number = v }
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
> 코틀린에서는 getter, setter 함수를 잘 쓰지 않습니다! 공식 문서를 가볍게 읽어보시면 좋을거 같아요!
|
|
69
|
+
|
|
70
|
+
→ Kotlin property가 자동 생성. 자바식 메서드 작성 = 코틀린 idiom 위반.
|
|
71
|
+
|
|
72
|
+
### 6. `LottoAdministrator` feature-envy
|
|
73
|
+
|
|
74
|
+
```kotlin
|
|
75
|
+
class LottoAdministrator(.) {
|
|
76
|
+
fun matchCount(lottoNumber: Lotto, winningNumber: Lotto): Int {
|
|
77
|
+
return lottoNumber.numbers.filter { it in winningNumber.numbers }.size
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
> lottoNumber와 winningNumber 객체의 numbers를 가져와서 확인하는 함수네요, 객체의 데이터를 쓰기보다, 메세지를 전달하여 책임을 위임해보면 어떨까요?
|
|
83
|
+
|
|
84
|
+
→ `winningLotto.match(lotto): Rank`.
|
|
85
|
+
|
|
86
|
+
## 리뷰어 의견 요지
|
|
87
|
+
|
|
88
|
+
리뷰어 @namjackson의 가르침:
|
|
89
|
+
|
|
90
|
+
1. **함수명과 책임의 일치**.
|
|
91
|
+
|
|
92
|
+
2. **값 객체 만들었으면 그 객체로 다루기** — `Count` 반환.
|
|
93
|
+
|
|
94
|
+
3. **Kotlin property 활용** — getter/setter 메서드 회피.
|
|
95
|
+
|
|
96
|
+
4. **Tell-Don't-Ask** — feature-envy 회피.
|
|
97
|
+
|
|
98
|
+
- **대표 인용:**
|
|
99
|
+
> 2등과 3등의 countOfMatch가 일치하네요, Rank에서 2등과 3등을 어떻게 분리를 할수 있을까요? Bonus볼의 여부도 Rank의 책임이 아닐까요?
|
|
100
|
+
>
|
|
101
|
+
> — @namjackson on `src/main/kotlin/domain/Rank.kt`
|
|
102
|
+
|
|
103
|
+
> 객체의 데이터를 쓰기보다, 메세지를 전달하여 책임을 위임해보면 어떨까요?
|
|
104
|
+
>
|
|
105
|
+
> — @namjackson on `src/main/kotlin/domain/LottoAdministrator.kt`
|
|
106
|
+
|
|
107
|
+
## 얻은 교훈
|
|
108
|
+
|
|
109
|
+
- **값 객체 만든 후 *그 타입으로 다루기***. Count 만들고 Int 반환 = wrapping 의미 없음.
|
|
110
|
+
- **Kotlin property = 자동 getter/setter**. `var number: Int`만 쓰면 자바의 `getNumber/setNumber` 자동 생성. 직접 작성 ≠ Kotlin idiom.
|
|
111
|
+
- **5개 일치 두 케이스 = Rank가 matchBonus 데이터 보유**. enum의 판별 데이터.
|
|
112
|
+
- **`LottoAdministrator` 같은 외부 비교자 = feature-envy 신호**. `winningLotto.match(lotto)` 메시지로.
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# PR #75 — [심지] 1단계 로또
|
|
2
|
+
|
|
3
|
+
- **Reviewee:** [@sh1mj1](https://github.com/sh1mj1)
|
|
4
|
+
- **PR:** https://github.com/woowacourse/kotlin-lotto/pull/75
|
|
5
|
+
- **단계:** 1단계
|
|
6
|
+
- **리뷰어:** @malibinYun (말리빈)
|
|
7
|
+
- **라인 코멘트:** 15
|
|
8
|
+
|
|
9
|
+
## 잘한 점 (설계 관점)
|
|
10
|
+
|
|
11
|
+
- **`evaluator.evaluate()` 같은 *동어반복* 학생이 자발적 지적**.
|
|
12
|
+
- **`Money` data class vs equals/hashCode 직접 override 학생 자가 비교**.
|
|
13
|
+
- **`WinningRank.NONE`의 `matchNumbers(0)`이 *사실상 실제 값이 아님*을 학생이 지적**.
|
|
14
|
+
- **TDD로 인한 *public 강제*에 대한 자가 분석** (블로그 링크 포함 — 정리한 학생).
|
|
15
|
+
- **책임 주도 설계 5단계를 *자가 인용*** (조영호 *오브젝트* 책 정리).
|
|
16
|
+
- **자가 결론에 *기준과 근거*** — "*정답을 찾는 것도 좋지만, 자신만의 기준과 근거를 세우는 것이 중요*하다는 이야기를 들었습니다."
|
|
17
|
+
|
|
18
|
+
## 못한 점 (설계 관점)
|
|
19
|
+
|
|
20
|
+
### 1. `Evaluator.evaluate()` *동어반복* 네이밍
|
|
21
|
+
|
|
22
|
+
학생: "이 코드의 클라이언트에서 *evaluate 메서드를 호출할 때, lotteryRankEvaluator.evaluate()의 모습처럼 객체 이름과 메서드의 이름이 중복*되고, *저는 이 중복이 불필요*하다고 느꼈기 때문입니다. 하지만 *다른 네이밍을 고민해 봐도 생각나는 것이 없었*습니다. 리뷰어님께서는 *이러한 불편함을 어떻게 해결*하시나요? 고민에 대해서도 말씀해 주신 *객체 간의 협력을 중심으로 생각하고 설계하다 보면, 네이밍의 문제가 자연스럽게 해결*될까요?"
|
|
23
|
+
|
|
24
|
+
→ *Ranker.of(lotto, winningLotto)* 같은 *정적 팩토리*가 자연.
|
|
25
|
+
|
|
26
|
+
### 2. `Money` *data class vs 직접 override*
|
|
27
|
+
|
|
28
|
+
학생: "*data class 를 사용한다면 private constructor 를 사용하기를 권고하지 않기 때문*입니다.(컴파일러 warning) 경고가 생기는 이유는 *data class로 선언 시 copy라는 메서드를 사용할 수 있게 되는데, 이 때문에 진정한 private constructor가 아니게 되기 때문*입니다. 1. data class를 사용한다. →. 다른 클라이언트 코드에서 Money를 잘못 사용하는 경우를 감안하고 넘어간다. 2. data class를 사용하지 않고 직접 equals와 hashCode, toString 메서드를 오버라이드한다. → 코드가 매우 더러워진다. *리뷰어님은 1번과 2번 중 어떠한 것이 더 좋은 생각이라고 생각하시나요?*"
|
|
29
|
+
|
|
30
|
+
리뷰어: "심지는 어떤 것이 더 좋은 생각이라고 생각하시나요? *반드시 다른 하나는 '나쁜 것' 이었나요*?"
|
|
31
|
+
|
|
32
|
+
학생 (재성찰): "저는 *2번의 방법이 더 적합*하다고 생각을 했습니다. 왜냐하면 직접 equals와 hashCode, toString 메서드를 오버라이드해서 생기는 문제보다는 *Money의 인스턴스를 생성하는 방법을 하나로만 지정해서, 추후에 다른 개발자가 Money 클래스를 사용할 때 생기는 실수나 코드의 반복을 줄이는 것이 더 도움*이 된다고 생각했기 때문입니다.. [P.S] *정답을 찾는 것도 좋지만, 자신만의 기준과 근거를 세우는 것이 중요*하다는 이야기를 들었습니다. 저도 리뷰어님의 의견을 절대적인 정답이라고 생각하지는 않고 제 기준을 세우겠습니다!"
|
|
33
|
+
|
|
34
|
+
리뷰어: "*원론으로 돌아가서, private constructor를 사용할 필요가 있었는지? 그 이유는 무엇이었는지? 를 더 캐묻겠습니다* 😈" — *전제 자체를 의심*.
|
|
35
|
+
|
|
36
|
+
### 3. `WinningRank.NONE` *값 아님*
|
|
37
|
+
|
|
38
|
+
```kotlin
|
|
39
|
+
enum class WinningRank(val matchNumbers: Int,.) {
|
|
40
|
+
.
|
|
41
|
+
NONE(0,.) // ⚠ '0'은 실제 등수 정보가 아님
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
학생: "*NONE이라는 entry에서의 matchNumbers(0)은 사실상 실제 값이 아니게 되었습니다*. enum class를 사용하면서 이 문제를 해결할 수 있는 방법이 있을까요?"
|
|
46
|
+
|
|
47
|
+
리뷰어: "*0, 1, 2를 갖게 하는 열거형을 가지게 된다면 어떤 장단점이 있었나요*? 원하는 문제를 해결해 볼 수 있었나요? *또 다른 문제가 생겼다면, 그것은 어떻게 해결*해 볼 수 있을까요? *완벽한 정답은 존재하지 않는다는 것을 유념*해 주세요 :)"
|
|
48
|
+
|
|
49
|
+
→ *Range-based matching* (`matchNumbers <= 2 → NONE`)이나 *sealed class*로 *0-2 미만*을 명시 가능.
|
|
50
|
+
|
|
51
|
+
### 4. `WinningResult`의 `Map<Rank, Int>` — *Int 포장 여부*
|
|
52
|
+
|
|
53
|
+
학생: "요구사항: *모든 원시 값과 문자열을 포장한다*. WinningResult의 프로퍼티인 맵의 *Int 값은 당첨의 개수*를 의미합니다. *물론 이 클래스만 봐서는 Int 값이 당첨의 개수를 의미한다는 것을 알기 힘듭니다. 하지만 그 이유로 이 Int 값도 포장할 이유가 있을까요*? 저는 *과도한 포장*이라고 생각하였습니다. 하지만 리뷰어님은 어떻게 생각하시는지 궁금합니다. 또 *원시값 포장을 사용하지 않으면서, 이 클래스만 보고 Int 값이 어떤 값을 나타내는지 알려줄 수 있는 또 다른 방법*이 있나요? (주석을 작성하지 않고)"
|
|
54
|
+
|
|
55
|
+
리뷰어: "*개발의 세계에 맞고 틀림을 논하는 건 생각보다 진흙탕 싸움일 수 있어요. 누구도 이길 수 없는 게임을 하는 것일지도 몰라요. 포장했을 때는 어떤 장단점이 있었나요? 포장을 해야 하는 이유에 대해서도 많은 생각을 해 보는 건 어떨까요?*" + "*극단적으로 연습을 해보는 것도 좋은 방법*이에요! 나중에 *포장된 값을 풀어내는 것은 언제든지 가능*하지만, *포장하는 연습을 해본 적이 없는 사람은, 애초에 포장 자체를 못할 가능성*이 있어요 :)"
|
|
56
|
+
|
|
57
|
+
학생: "*제가 원시값 포장을 하지 않은 이유는 설계/구현 단계에서는 원시값으로 포장을 하여 객체를 만들더라도, 그 클래스 안에 유효성 검증이나, equals 등의 어떠한 로직도 필요없기 때문*이었습니다. 하지만 *제가 아직 원시값을 사용했을 때의 이점을 설명할 정도로 알고 있지 않은 것 같네요*! 이 부분은 제가 더 공부해 보겠습니다!!"
|
|
58
|
+
|
|
59
|
+
### 5. *TDD가 public 강요*? 학생 자가 분석
|
|
60
|
+
|
|
61
|
+
학생 (블로그 링크 첨부): "엄밀히 말하면 *TDD 때문에 메서드가 public이 된 건 아닌 것 같*습니다. 저는 우테코 프리코스 과정 중에 *TDD에 대해 알아보고, 장/단점을 [공부한 경험](https://sh1mj1-log.tistory.com/184)*이 있습니다. 또 제가 *[오브젝트 책을 공부하면서](https://sh1mj1-log.tistory.com/141) 책임 주도 설계의 흐름*을 아래처럼 정리했었습니다.
|
|
62
|
+
> * 시스템이 사용자에게 제공해야 하는 기능인 시스템 책임을 파악함.
|
|
63
|
+
> * 시스템을 더 작은 책임으로 분할
|
|
64
|
+
> * 분할된 책임을 수행할 수 있는 적절한 객체 또는 역할을 찾아 책임 할당
|
|
65
|
+
> * 객체가 책임을 수행하는 도중 다른 객체의 도움이 필요하면 이를 책임질 적절한 객체 또는 역할을 찾음.
|
|
66
|
+
> * 해당 객체 또는 역할에게 책임을 할당하여 두 객체가 협력하게 함.
|
|
67
|
+
|
|
68
|
+
제가 처음 코드를 작성하기 전 기능 목록을 아래처럼 정리했었습니다. *'로또 번호와 당첨 번호, 보너스 번호를 비교하여 당첨 결과를 알려준다'*. 그런데 *이 기능 명세에서 객체의 책임을 더 분리하지 않았던 것 같*습니다. 위 책임에서 책임을 더 분리한다면, 아래처럼 분리할 수 있을 것 같아요.
|
|
69
|
+
> * 로또와 당첨번호가 일치하는 숫자의 갯수를 구한다.
|
|
70
|
+
> * 로또에 보너스번호가 있는지 여부를 구한다.
|
|
71
|
+
|
|
72
|
+
위처럼 책임을 분리할 수 있다는 사실은 LotteryRankEvaluator 객체의 책임인 evaluate의 책임에 대해서 *테스트를 먼저 작성하다가 알아냈*습니다. 이 때 *기능 목록을 수정하면서 객체를 분리할 수 있었지만, 그렇지 못한 것* 같습니다. *제가 공부하고 정리했던 TDD 도입에서의 단점*에서 이런 것이 있더라구요. *'초기 설계에 얽매이게 된다. 이 경우는 도메인에 대한 지식과 이해가 부족할수록 자주 일어난다.'* TDD 방법론 자체의 문제라기 보다는 *제가 책임을 분리하는 능력이 부족했던 탓*이네요.. *공부했던 내용인데 실제로 적용하기는 역시 훨씬 어렵군요.*"
|
|
73
|
+
|
|
74
|
+
리뷰어 "*'TDD 때문에 메서드가 public이 되었다'는 정말 사실일까요*? TDD로 개발하는 것은 매우 어려운 길이에요. 왜일까요? 정말로 *없는 코드에 대해 테스트를 먼저 작성하는 게 익숙하지 않아서일까요*? *없는 코드를 테스트한다는 말이 납득이 되실까요*? 코드를 치기 전, *먼저 기능 명세를 작성하듯이, 그 작성한 명세를 기반으로 객체 간의 협력을 설계*해 보세요 :) *그러면 그 객체가 다른 객체와 협력하기 위해 만들어야 하는 메서드들이 나오게 될 거에요. 그럼 그 메서드를 먼저 TDD로 옮기면 되겠지요. match와 bonusMatch는 다른 객체들과 협력하기 위해 설계된 메서드였나요*?"
|
|
75
|
+
|
|
76
|
+
→ *match*, *bonusMatch*가 *클라이언트와의 협력*이 아니라 *evaluate 내부의 헬퍼*였다면 *처음부터 private*. *테스트가 우선 도달*했다고 *public이 되는 것은 결과론*.
|
|
77
|
+
|
|
78
|
+
## 리뷰어 의견 요지
|
|
79
|
+
|
|
80
|
+
- **메타-질문으로 학생을 *재성찰 유도*** — "심지는 어떻게 생각하세요?", "반드시 나쁜 것이었나요?", "전제 자체를 캐묻겠습니다 😈".
|
|
81
|
+
- **객체 협력 설계가 우선, *TDD가 책임 결정자가 아님***.
|
|
82
|
+
- **포장은 *연습 단계에서 과하게*** — *풀어내기는 쉬움*.
|
|
83
|
+
- **완벽한 정답 없음** — *기준과 근거를 자기 것으로*.
|
|
84
|
+
|
|
85
|
+
- **대표 인용:**
|
|
86
|
+
> 심지는 어떤 것이 더 좋은 생각이라고 생각하시나요? *반드시 다른 하나는 '나쁜 것' 이었나요*?
|
|
87
|
+
> — @malibinYun on `src/main/kotlin/model/Money.kt`
|
|
88
|
+
|
|
89
|
+
> 개발의 세계에 *맞고 틀림을 논하는 건 생각보다 진흙탕 싸움일 수 있*어요. *누구도 이길 수 없는 게임*을 하는 것일지도 몰라요.
|
|
90
|
+
> — @malibinYun on `src/main/kotlin/model/WinningResult.kt`
|
|
91
|
+
|
|
92
|
+
> 코드를 치기 전, *먼저 기능 명세를 작성하듯이, 그 작성한 명세를 기반으로 객체 간의 협력을 설계*해 보세요. 그러면 *그 객체가 다른 객체와 협력하기 위해 만들어야 하는 메서드들이 나오게 될 거에요*. 그럼 그 메서드를 먼저 TDD로 옮기면 되겠지요.
|
|
93
|
+
> — @malibinYun on `src/main/kotlin/model/lottery/LotteryRankEvaluator.kt`
|
|
94
|
+
|
|
95
|
+
> 나중에 *포장된 값을 풀어내는 것은 언제든지 가능*하지만, *포장하는 연습을 해 본 적이 없는 사람은, 애초에 포장 자체를 못할 가능성*이 있어요 :)
|
|
96
|
+
> — @malibinYun on `src/main/kotlin/model/WinningResult.kt`
|
|
97
|
+
|
|
98
|
+
## 얻은 교훈
|
|
99
|
+
|
|
100
|
+
- **`Evaluator.evaluate()` 동어반복 회피** — *Ranker.of(lotto, winning)* 같이 *정적 팩토리*로 *주어 + 동작*을 *한 단어*에. 객체 협력 어휘는 *짧고 자연*.
|
|
101
|
+
- **`data class` vs `private constructor` 충돌** — *value class*가 표준 해법. 학생이 *직접 override*를 *코드 더러움*이라 자각.
|
|
102
|
+
- **`enum.NONE`의 *가짜 값* 문제** — *Sentinel 객체*가 *0/null* 보유는 *의미 없는 값*. *sealed class*로 *MissCase* 분리 가능.
|
|
103
|
+
- ***과도한 포장*에 대한 기준** — *유효성/equals 로직이 필요 없으면* 포장 가치 약함. 단 *연습 단계에선 과하게* 권장.
|
|
104
|
+
- **TDD가 *책임 결정*하지 않음** — *기능 명세 → 객체 협력 → 메서드*. *Test-first*가 *Design-first*를 대체하지 않음.
|