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,75 @@
|
|
|
1
|
+
# PR #139 — [로또 2단계] 미플 미션
|
|
2
|
+
|
|
3
|
+
- **Reviewee:** [@HamBeomJoon](https://github.com/HamBeomJoon)
|
|
4
|
+
- **PR:** https://github.com/woowacourse/kotlin-lotto/pull/139
|
|
5
|
+
- **단계:** 2단계
|
|
6
|
+
- **리뷰어:** @hyemdooly
|
|
7
|
+
- **라인 코멘트:** 51
|
|
8
|
+
|
|
9
|
+
## 못한 점 (설계 관점)
|
|
10
|
+
|
|
11
|
+
### 1. View가 도메인 검증 (로또 개수 범위)
|
|
12
|
+
|
|
13
|
+
```kotlin
|
|
14
|
+
fun readManualCount(maxCount: Int): Int {
|
|
15
|
+
val count = readln().toInt()
|
|
16
|
+
require(count in 0..maxCount) // ⚠ View가 도메인 invariant 검증
|
|
17
|
+
}
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
> 로또 개수 범위에 대한 검증 로직은 뷰의 로직일까요?
|
|
21
|
+
|
|
22
|
+
→ 도메인 invariant는 도메인 init.
|
|
23
|
+
|
|
24
|
+
### 2. `Set`/`List` 혼용
|
|
25
|
+
|
|
26
|
+
```kotlin
|
|
27
|
+
fun match(lotto: Lotto): Rank {
|
|
28
|
+
val winningSet = winning.numbers.toSet() // ⚠ 매번 변환
|
|
29
|
+
return.
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
> 왜 Set으로 변환하는 함수가 들어가게 되었는지 궁금해요!
|
|
34
|
+
> 여기가 `List`로 바뀐 이유는 편의성 때문일까요?
|
|
35
|
+
|
|
36
|
+
→ 자료구조 선택 = 호출 위치마다 다르지 않게. 도메인 객체가 *적절한 자료구조*를 내부 보유.
|
|
37
|
+
|
|
38
|
+
### 3. `Pair`로 자동/수동 로또 반환
|
|
39
|
+
|
|
40
|
+
```kotlin
|
|
41
|
+
fun purchaseLottos(.): Pair<LottoTicket, LottoTicket> {. }
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
> `Pair`를 사용할 수도 있어요! (긍정)
|
|
45
|
+
> 구조 분해 활용 👍
|
|
46
|
+
|
|
47
|
+
학생이 자가 의문:
|
|
48
|
+
|
|
49
|
+
> 1. getResult 함수에 넘겨줄 때 LottoTicket 리스트를 합쳐서 넣어주기
|
|
50
|
+
> 2. 자동 로또와 수동 로또를 구분해서 넣어주기
|
|
51
|
+
> 어떤 방식이 더 좋을까요?
|
|
52
|
+
|
|
53
|
+
→ 합쳐서 넘기는 게 *호출자 단순*, 구분해서 넘기는 게 *통계 표시 시 유리*. 둘 중 호출 패턴이 결정.
|
|
54
|
+
|
|
55
|
+
### 4. `value class` 사용 의도?
|
|
56
|
+
|
|
57
|
+
> `value class`는 어떤 특징이 있을까요?
|
|
58
|
+
|
|
59
|
+
→ inline + 단일 값 wrapper. data class보다 런타임 오버헤드 적음.
|
|
60
|
+
|
|
61
|
+
### 5. View 테스트 — 요구사항 아님
|
|
62
|
+
|
|
63
|
+
```kotlin
|
|
64
|
+
class InputTest {. }
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
> 이번 미션에서 View 테스트는 요구사항이 아니었다고 하더라구요
|
|
68
|
+
|
|
69
|
+
→ Controller/View 테스트는 *통합 테스트* 자리.
|
|
70
|
+
|
|
71
|
+
## 얻은 교훈
|
|
72
|
+
|
|
73
|
+
- **자료구조 변환을 호출 위치마다 하지 말 것**. 도메인이 *적절한 형태*로 보관 (Set vs List).
|
|
74
|
+
- **자동/수동 분리 vs 합치기 = 호출 패턴에 따라**. 통계 표시에 분리 필요하면 분리, 단순 매칭이면 합치기.
|
|
75
|
+
- **View 테스트 회피** — 단위 테스트 부적합, 통합 테스트 자리.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# PR #76 — [로또] 팡태 1단계 미션
|
|
2
|
+
|
|
3
|
+
- **Reviewee:** [@Hevton](https://github.com/Hevton)
|
|
4
|
+
- **PR:** https://github.com/woowacourse/kotlin-lotto/pull/76
|
|
5
|
+
- **단계:** 1단계
|
|
6
|
+
- **리뷰어:** @ghojeong
|
|
7
|
+
- **라인 코멘트:** 12
|
|
8
|
+
|
|
9
|
+
## 잘한 점
|
|
10
|
+
|
|
11
|
+
- **`TicketGenerationStrategy` 전략 패턴** — 칭찬.
|
|
12
|
+
|
|
13
|
+
학생:
|
|
14
|
+
|
|
15
|
+
> 전략 패턴을 쉽게, 확장성있게 이용할 수 있도록 제공하고 있는가
|
|
16
|
+
> 거창하게 전략 패턴이라고 말을 하지만, 실상은 티켓을 발행하는 로직을 interface 로 추상화한게.
|
|
17
|
+
|
|
18
|
+
## 얻은 교훈
|
|
19
|
+
|
|
20
|
+
- **전략 패턴의 본질 = 인터페이스 추상화** + 구현체 교체.
|
|
21
|
+
- **거창한 이름 vs 단순 추상화** — 패턴 이름에 매몰되지 말고 본질에 집중.
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# PR #92 — [로또] 팡태 2단계 미션
|
|
2
|
+
|
|
3
|
+
- **Reviewee:** [@Hevton](https://github.com/Hevton)
|
|
4
|
+
- **PR:** https://github.com/woowacourse/kotlin-lotto/pull/92
|
|
5
|
+
- **단계:** 2단계 (수동 로또 추가)
|
|
6
|
+
- **리뷰어:** @ghojeong (파이로)
|
|
7
|
+
- **라인 코멘트:** 38
|
|
8
|
+
|
|
9
|
+
## 잘한 점 (설계 관점)
|
|
10
|
+
|
|
11
|
+
- **`MixedTicketGenerationStrategy` 도입** — 자동/수동 통합 전략. `Ticket` 단위 발행이라는 도메인 제약을 인식.
|
|
12
|
+
- **유효성 검증을 `LotteryPurchasePattern`로 캡슐화 시도** — 수동/자동 수 계산 + 검증을 한 곳에.
|
|
13
|
+
- **`safe {. }` helper로 컨트롤러 흐름 통일** — 모든 입력을 동일한 패턴으로 감쌈.
|
|
14
|
+
- **자가 의문 PR에 풍부히 명시** — 학생이 "처음부터 다시 구성해야 될지도 모르겠다"는 깨달음을 PR에 적음.
|
|
15
|
+
|
|
16
|
+
## 못한 점 (설계 관점)
|
|
17
|
+
|
|
18
|
+
### 1. 통합 전략 도입 후에도 `RandomTicketGenerationStrategy` 잔존
|
|
19
|
+
|
|
20
|
+
```kotlin
|
|
21
|
+
class RandomTicketGenerationStrategy(private val amount: Amount) : TicketGenerationStrategy {
|
|
22
|
+
override fun issueTicket(): Ticket {
|
|
23
|
+
val lotteries = mutableListOf<Lottery>()
|
|
24
|
+
repeat(amount.money / LOTTO_TICKET_PRICE) {
|
|
25
|
+
lotteries.add(Lottery(RandomLotteryGenerator.generateNumbers()))
|
|
26
|
+
}
|
|
27
|
+
return Ticket(lotteries, amount, LotteryPurchasePattern(0, lotteries.size))
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
리뷰어: "만약 MixedTicketGenerationStrategy로 충분하다고 생각하셨다면, 기존의 RandomTicketGenerationStrategy를 왜 남겨두셨는지 궁금합니다. 추후에 어떻게 활용하겠다는 계획이 있으시나요?" 학생: "프로덕션이 아니라 학습 과정이라 흔적으로 남겨놓을까 생각" — 학습용은 양해될 수 있으나, *통합 후 남은 추상*은 미래 동료에게는 "어느 걸 써야 할지" 신호.
|
|
33
|
+
|
|
34
|
+
### 2. `ExplicitTicketGenerationStrategy`는 *테스트 의존성 분리* 관점에서 살아남음
|
|
35
|
+
|
|
36
|
+
리뷰어: "MixedTicketGenerationStrategy는 로또 티켓 발행의 핵심 로직 중 하나이고, 언제든 다른 개발자가 만든 Strategy로 변경될 수 있습니다. 단, 다른 Strategy로 변경되었을 때 팡태님이 작성하신 코드의 테스트가 실패해서는 안됩니다." — 테스트가 *프로덕션 전략*에 의존하면 프로덕션 변경 시 테스트 함께 깨짐. 테스트 전용 Strategy는 *의존성 차단*의 도구.
|
|
37
|
+
|
|
38
|
+
### 3. `LotteryPurchasePattern` = data 컨테이너 + 검증
|
|
39
|
+
|
|
40
|
+
```kotlin
|
|
41
|
+
class LotteryPurchasePattern(val manualLottoCount: Int, val autoLottoCount: Int) {
|
|
42
|
+
companion object {
|
|
43
|
+
fun ofManual(amount: Amount, input: String): LotteryPurchasePattern {. }
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
리뷰어 분석: "유효성 검사는 현재 객체가 상태를 갖기 전 '생성'할 때 적용되는 로직이고, 객체가 실제로 상태를 가진 후에 갖게 되는 로직은 현재 전혀 없습니다. 상태를 갖기 전의 로직은 극단적으로 말해서, 외부 유틸의 static 메서드로 제공되어도 아무 문제가 없습니다." — "구매 패턴"이라는 이름이라면 *현재 수동/자동이 가능한 상태인지 알려주는* boolean이나 *실제로 발행하는 로직*이 있어야 객체. 지금은 *struct + factory*에 가까움.
|
|
49
|
+
|
|
50
|
+
### 4. Controller에 if/매직넘버 분기
|
|
51
|
+
|
|
52
|
+
```kotlin
|
|
53
|
+
private fun issueTicket(amount: Amount, lotteryPurchasePattern: LotteryPurchasePattern): Ticket {
|
|
54
|
+
var manualLotteryCandidates = listOf<String>()
|
|
55
|
+
if (lotteryPurchasePattern.manualLottoCount > 0) {
|
|
56
|
+
manualLotteryCandidates = readManualLotteryCandidates(lotteryPurchasePattern)
|
|
57
|
+
}
|
|
58
|
+
.
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
리뷰어: "모든 종류의 매직넘버 상수화 부탁드립니다. 그리고 Controller에 조건문 혹은 반복문이 있을 경우, 가능한 model의 테스트 가능한 비즈니스 로직으로 옮길 수 있도록 부탁드립니다." — Controller의 분기는 *조립*이지 *판단*이 아님. `lotteryPurchasePattern.hasManual()` 같은 메서드로 옮겨야 단위 테스트 가능.
|
|
63
|
+
|
|
64
|
+
### 5. `safe {. }` — try-catch 일괄 흡수
|
|
65
|
+
|
|
66
|
+
```kotlin
|
|
67
|
+
val amount = safe { readAmount() }
|
|
68
|
+
val lotteryPurchasePattern = safe { readPurchasePattern(amount) }
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
리뷰어가 길게 안내: "안드로이드 개발 시에는 핸들링되지 않는 모든 예외를 던지지 않도록 한다. 가능한 default 값이 반환되면 좋고, default 값이 없다면 null이 반환되어야 합니다. null 대신 default 값을 선호하는 이유는 null이 NullException 예외를 발생시켜, 마찬가지로 앱이 크래시 나게 만들 위험이 있기 때문입니다." — `safe`는 흐름을 통일했지만, *어떤 오류가 어떻게 핸들링되는지*는 호출자에게 보이지 않음 — 단지 "예외가 어딘가에서 사라진다."
|
|
72
|
+
|
|
73
|
+
### 6. 가변 리스트로 누적
|
|
74
|
+
|
|
75
|
+
```kotlin
|
|
76
|
+
private fun generateRandomLotteries(): List<Lottery> {
|
|
77
|
+
val lotteries = mutableListOf<Lottery>()
|
|
78
|
+
repeat(lotteryPurchasePattern.autoLottoCount) {
|
|
79
|
+
lotteries.add(Lottery(RandomLotteryGenerator.generateNumbers()))
|
|
80
|
+
}
|
|
81
|
+
return lotteries
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
리뷰어 제안: `List(count) { Lottery(.) }`로 *불변 리스트*. *누적*이라는 절차가 *생성*이라는 의도로 바뀜.
|
|
86
|
+
|
|
87
|
+
### 7. `LotteryPurchasePattern`의 이름과 실체 불일치
|
|
88
|
+
|
|
89
|
+
학생 의도: "수동 로또: 3, 자동 로또: 2 라는 결과를 계산해 주면서 각 값 또한 멤버로 갖고 있는 '구매 패턴에 대한 책임을 갖는' 클래스." 리뷰어: "이 숫자 데이터는 캡슐화되어 접근할 수 없고, 실제로 로또를 발행하거나, … boolean 값을 계산해서 보여주지 않을까 기대했습니다." — *Pattern*은 행위/규칙을 시사 — 단순 컨테이너라면 `LottoOrder` 같은 명사형.
|
|
90
|
+
|
|
91
|
+
## 리뷰어 의견 요지
|
|
92
|
+
|
|
93
|
+
1. **통합 추상 도입 후 *이전 추상* 정리** — 학습용으로 남겨도, 미래 동료가 "왜 살아 있나"를 묻는다.
|
|
94
|
+
2. **테스트 의존성은 프로덕션 의존성과 분리** — 테스트 Strategy(`Explicit`)는 프로덕션이 어떻게 바뀌어도 깨지지 않는 *고정 기준*.
|
|
95
|
+
3. **"객체"는 *상태 + 그 상태로 하는 일*** — 생성 시 검증만 있는 클래스는 C struct 수준. 클래스로 만들었으면 *상태로 무언가를 해야* 한다.
|
|
96
|
+
4. **"앱이 죽지 않게"가 예외 처리의 1차 목표** — *논리 오류*/*비논리 오류* 구분에 매몰되지 말고, *던져지지 않는 길*을 먼저 모색.
|
|
97
|
+
5. **테스트 코드 작성 가능성 = 논리 오류 판별 기준** — 학생이 헷갈리는 *논리 오류 vs 비논리 오류*에 대해, 리뷰어가 실용적 기준을 제시 — "테스트 코드로 작성 가능하면 논리 오류".
|
|
98
|
+
6. **Controller에 조건문 = 테스트 불가 로직** — 조건은 도메인 메서드로 내려야 단위 테스트로 검증 가능.
|
|
99
|
+
|
|
100
|
+
- **대표 인용:**
|
|
101
|
+
> 만약 MixedTicketGenerationStrategy로 충분하다고 생각하셨다면, 기존의 RandomTicketGenerationStrategy를 왜 남겨두셨는지 궁금합니다.
|
|
102
|
+
> — @ghojeong on `src/main/kotlin/utils/RandomTicketGenerationStrategy.kt`
|
|
103
|
+
|
|
104
|
+
> 객체는 상태(멤버)와 그에 따른 로직(메서드)를 통해 그 역할과 책임이 나타납니다. 유효성 검사는 현재 객체가 상태를 갖기 전 "생성"할 때 적용되는 로직이고, 객체가 실제로 상태를 가진 후에 갖게 되는 로직은 현재 전혀 없습니다.
|
|
105
|
+
> — @ghojeong on `src/main/kotlin/model/LotteryPurchasePattern.kt`
|
|
106
|
+
|
|
107
|
+
> 안드로이드 개발 시에는 핸들링되지 않는 모든 예외를 던지지 않도록 한다. 라고 생각해 주세요.
|
|
108
|
+
> — @ghojeong on `src/main/kotlin/controller/LotteryController.kt`
|
|
109
|
+
|
|
110
|
+
> 무엇이 논리 오류인지, 아닌지 판별하기 어려우시면, 저는 "테스트 코드"를 기준으로 판별하라고 하고 싶습니다.
|
|
111
|
+
> — @ghojeong on `src/main/kotlin/controller/LotteryController.kt`
|
|
112
|
+
|
|
113
|
+
## 얻은 교훈
|
|
114
|
+
|
|
115
|
+
- **통합 추상 후 이전 추상 정리**. 통합 객체와 개별 객체가 공존하면 사용자가 *둘 중 무엇*을 써야 할지 매번 판단해야 함. 학습 흔적은 README/위키로.
|
|
116
|
+
- **테스트 Strategy는 *분리* 자산**. 프로덕션 Strategy를 테스트에 그대로 쓰면 프로덕션 변경이 테스트 검증을 깬다. 테스트 전용 객체는 *시간에 따라 안 변하는 기준점*.
|
|
117
|
+
- **"클래스"는 *상태로 무엇을 하는가* 가 있어야**. 생성 검증만 있는 클래스는 C struct + factory. 진짜 객체가 되려면 *상태를 사용한 메서드*가 있어야 함 — 없으면 `data class`로 솔직히.
|
|
118
|
+
- **이름이 *Pattern*/*Manager*/*Handler*면 *행위*가 있어야**. 명사형 이름과 실체가 *컨테이너*면 동료가 두 번 본다.
|
|
119
|
+
- **Controller에 조건/반복 ≈ 테스트 불가 로직**. Controller는 *조립*만, 분기/반복은 도메인 메서드로 내림.
|
|
120
|
+
- **예외 처리는 *논리/비논리 분류*가 아니라 *크래시 방지*가 1차 목표**. 분류는 *유용한 휴리스틱*이지 *교조*가 아님.
|
|
121
|
+
- **테스트 가능성 = 논리 오류 판별 기준**. "이 오류가 발생하는 상황을 단위 테스트로 쓸 수 있는가?" — 가능하면 논리 오류 → 그 자체로 *명시적 핸들링*이 가능.
|
|
122
|
+
- **콘솔 프로그램 ≠ Android 앱**. sealed class 결과 타입은 *옵저버 패턴이 있는 곳*에서 진가가 발휘됨. 콘솔에서는 try-catch + 재시도가 더 단순할 수 있음 — 패턴은 *맥락*에 종속.
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# PR #100 — [로또] 악어 2단계 미션
|
|
2
|
+
|
|
3
|
+
- **Reviewee:** [@Hogu59](https://github.com/Hogu59)
|
|
4
|
+
- **PR:** https://github.com/woowacourse/kotlin-lotto/pull/100
|
|
5
|
+
- **단계:** 2단계
|
|
6
|
+
- **리뷰어:** @Gyuil-Hwnag
|
|
7
|
+
- **라인 코멘트:** 66
|
|
8
|
+
|
|
9
|
+
## 잘한 점 (설계 관점)
|
|
10
|
+
|
|
11
|
+
- **`Money` 검증 + `Count` 값 객체 도입**.
|
|
12
|
+
- **`toIntOrNull() + require`** — 코틀린 idiom.
|
|
13
|
+
- **1단계 피드백 흡수** — readln()을 InputView로 이동.
|
|
14
|
+
|
|
15
|
+
## 못한 점 (설계 관점)
|
|
16
|
+
|
|
17
|
+
### 1. try-catch 잔존 (`runCatching` 미적용)
|
|
18
|
+
|
|
19
|
+
```kotlin
|
|
20
|
+
fun readCount(): Int {
|
|
21
|
+
return try {
|
|
22
|
+
InputView.readCount()
|
|
23
|
+
} catch (e: IllegalArgumentException) {
|
|
24
|
+
println(e.message)
|
|
25
|
+
readCount()
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
> 이번 미션 힌트에서 `try-catch`를 사용하지 않고 다른 방법을 사용하도록 적혀져 있는데, 과연 그말이 `runCatching`을 사용하도록 한 것인지 고민해보시면 좋을 것 같습니다.
|
|
31
|
+
|
|
32
|
+
→ try-catch 회피 ≠ runCatching 사용. *예외 자체를 안 던지는* 설계가 더 본질.
|
|
33
|
+
|
|
34
|
+
### 2. 수동 로또 입력이 Controller에
|
|
35
|
+
|
|
36
|
+
```kotlin
|
|
37
|
+
class LotteryController {
|
|
38
|
+
private fun inputManualLotteries(count: Count): List<Lottery> {
|
|
39
|
+
return List(count.value) {
|
|
40
|
+
val numbers = InputView.readWinningNumbers() // ⚠ Controller가 직접 수동 입력
|
|
41
|
+
Lottery.of(numbers)
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
> 수동으로 로또를 입력받는 부분이 과연 LottoController의 역활인지 고민해보시면 좋을 것 같습니다!
|
|
48
|
+
|
|
49
|
+
→ 수동 로또 *생성 정책*은 도메인 (`ManualLotteryGenerator`). Controller는 *호출*만.
|
|
50
|
+
|
|
51
|
+
### 3. `Lottery`에서 빈 입력 검증
|
|
52
|
+
|
|
53
|
+
```kotlin
|
|
54
|
+
class Lottery(val numbers: List<LotteryNumber>) {
|
|
55
|
+
init {
|
|
56
|
+
require(numbers.isNotEmpty()) { ERROR_BLANK_INPUT } // ⚠ 도메인이 입력 형식 검증
|
|
57
|
+
.
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
> ERROR_BLANK_INPUT은 빈칸이 들어왔을 때의 오류를 검증하는 내용인데, 해당 내용이 Lottery에서 검증을 하는 것이 맞을까 라는 생각이 듭니다!
|
|
63
|
+
|
|
64
|
+
→ 빈 입력은 UI 형식 검증 (InputView). Lottery 도메인은 *6개 + 1-45 + 중복 없음*만.
|
|
65
|
+
|
|
66
|
+
### 4. data class vs value class 차이 자가 의문
|
|
67
|
+
|
|
68
|
+
```kotlin
|
|
69
|
+
data class Count(val value: Int) {. }
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
> data class와 value class가 존재하는데, 그 둘은 어떤 차이점을 가지고 있을까요?
|
|
73
|
+
|
|
74
|
+
→ Count(Int) 같은 단일 값 wrapper는 value class가 인라인 이점.
|
|
75
|
+
|
|
76
|
+
### 5. test fixture 개념 미인지
|
|
77
|
+
|
|
78
|
+
```kotlin
|
|
79
|
+
class CountTest {
|
|
80
|
+
@Test fun.() { val count = Count(5). }
|
|
81
|
+
@Test fun.() { val count = Count(3). }
|
|
82
|
+
// ⚠ 매번 새 인스턴스 생성, 중복
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
> 테스트 코드에는 test fixture 라는 개념이 존재하는데 내용을 살펴보고 해당 내용을 어떻게 수정하면 좋을지 고민해보시면 좋을 것 같다는 생각이 듭니다!
|
|
87
|
+
|
|
88
|
+
→ `@BeforeEach`로 fixture 준비.
|
|
89
|
+
|
|
90
|
+
## 리뷰어 의견 요지
|
|
91
|
+
|
|
92
|
+
리뷰어 @Gyuil-Hwnag의 가르침:
|
|
93
|
+
|
|
94
|
+
1. **try-catch 회피의 진짜 의미** — runCatching 사용이 아닌 *예외를 던질 일 자체를 줄이기*.
|
|
95
|
+
|
|
96
|
+
2. **검증의 3분류 재확인** — 빈 입력 = UI, 도메인 = 6개/1-45/중복.
|
|
97
|
+
|
|
98
|
+
3. **수동 입력 정책의 자리** — Controller에서 도메인으로.
|
|
99
|
+
|
|
100
|
+
- **대표 인용:**
|
|
101
|
+
> 이번 미션 힌트에서 `try-catch`를 사용하지 않고 다른 방법을 사용하도록 적혀져 있는데, 과연 그말이 `runCatching`을 사용하도록 한 것인지 고민해보시면 좋을 것 같습니다
|
|
102
|
+
>
|
|
103
|
+
> — @Gyuil-Hwnag on `src/main/kotlin/controller/LotteryController.kt`
|
|
104
|
+
|
|
105
|
+
## 얻은 교훈
|
|
106
|
+
|
|
107
|
+
- **"try-catch 회피"의 본질 = 예외 발생을 *설계로* 줄이기**. runCatching은 *catch의 다른 표현*. 그보다 도메인이 *유효한 값만 받게*.
|
|
108
|
+
- **수동/자동 로또 생성 정책** = 도메인 (Generator 구현체). Controller는 어떤 Generator를 쓸지 *선택*만.
|
|
109
|
+
- **value class > data class (단일 값)** — racingcar 카드에서도 언급. lotto에서도 동일.
|
|
110
|
+
- **`@BeforeEach` test fixture** — 같은 setup 반복 제거.
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# PR #68 — [로또] 악어 step1 미션 제출합니다
|
|
2
|
+
|
|
3
|
+
- **Reviewee:** [@Hogu59](https://github.com/Hogu59)
|
|
4
|
+
- **PR:** https://github.com/woowacourse/kotlin-lotto/pull/68
|
|
5
|
+
- **단계:** 1단계
|
|
6
|
+
- **리뷰어:** @Gyuil-Hwnag
|
|
7
|
+
- **라인 코멘트:** 64
|
|
8
|
+
|
|
9
|
+
## 잘한 점 (설계 관점)
|
|
10
|
+
|
|
11
|
+
- **`Lottery`, `LotteryNumber`, `Profit`, `LotteryRankEvaluator`, `LotteryGenerator` 분리**.
|
|
12
|
+
- **`init {}` 블록 검증** — invariant.
|
|
13
|
+
- **`companion object` 상수**.
|
|
14
|
+
|
|
15
|
+
## 못한 점 (설계 관점)
|
|
16
|
+
|
|
17
|
+
### 1. `Profit` class 사용 이유 모호
|
|
18
|
+
|
|
19
|
+
```kotlin
|
|
20
|
+
class Profit(val rate: Double) {
|
|
21
|
+
fun show(): String =.
|
|
22
|
+
}
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
> Profit을 Class로 구현하신 이유가 궁금합니다! Profit이 이윤이라는 의미에서 좋기는 하나 다른 좀 더 친숙한 표현이 있는지도 고민해봐도 좋을 것 같습니다.
|
|
26
|
+
|
|
27
|
+
→ `Profit` (이윤) vs `ProfitRate` (수익률) — lotto 도메인에서는 후자가 의도. 이름이 정확해야 의도 표현.
|
|
28
|
+
|
|
29
|
+
### 2. `LotteryRankEvaluator` 인터페이스 미적용
|
|
30
|
+
|
|
31
|
+
```kotlin
|
|
32
|
+
class LotteryRankEvaluator(.) {
|
|
33
|
+
fun evaluate(.): Rank =.
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
> LotteryRankEvaluator는 확장성을 interface로 구현해봐도 좋겠다는 생각이 드네요.
|
|
38
|
+
|
|
39
|
+
→ "Evaluator" 같은 행위 클래스는 인터페이스 후보. 등수 계산 정책이 바뀔 가능성 있음.
|
|
40
|
+
|
|
41
|
+
### 3. 상수화 과잉
|
|
42
|
+
|
|
43
|
+
```kotlin
|
|
44
|
+
class LotteryNumber {
|
|
45
|
+
companion object {
|
|
46
|
+
const val MIN_LOTTERY_NUMBER = 1
|
|
47
|
+
const val MAX_LOTTERY_NUMBER = 45
|
|
48
|
+
}
|
|
49
|
+
init { require(value in MIN_LOTTERY_NUMBER..MAX_LOTTERY_NUMBER) }
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
> MIN_LOTTERY_NUMBER, MAX_LOTTERY_NUMBER를 상수로 뽑아서 관리하는 것도 좋지만, 자칫 지나친 상수화는 가독성을 떨어뜨릴 수도 있는 것 같습니다.
|
|
54
|
+
|
|
55
|
+
→ trade-off — 1, 45 같이 도메인 의미가 *영구한* 숫자는 상수화 가치 있음. 하지만 도메인 무지인이 봐도 1, 45가 *로또 번호 범위*라는 게 명확하면 인라인도 OK.
|
|
56
|
+
|
|
57
|
+
### 4. 분기 기준 자가 의문
|
|
58
|
+
|
|
59
|
+
학생 의문 (PR 본문):
|
|
60
|
+
|
|
61
|
+
> 또한 함수를 구분할 때 어떤 기준을 가지고 구분하고 계시는지 궁급합니다.
|
|
62
|
+
|
|
63
|
+
→ 리뷰어가 직접 답을 안 주고 학생 스스로 기준 정립 유도.
|
|
64
|
+
|
|
65
|
+
## 리뷰어 의견 요지
|
|
66
|
+
|
|
67
|
+
리뷰어 @Gyuil-Hwnag의 가르침:
|
|
68
|
+
|
|
69
|
+
1. **`Profit` vs `ProfitRate`** — 이름이 정확해야 도메인 의도 표현.
|
|
70
|
+
|
|
71
|
+
2. **상수화 trade-off** — 의미 명확한 매직넘버는 인라인도 가능.
|
|
72
|
+
|
|
73
|
+
3. **Evaluator 인터페이스 확장성**.
|
|
74
|
+
|
|
75
|
+
- **대표 인용:**
|
|
76
|
+
> MIN_LOTTERY_NUMBER, MAX_LOTTERY_NUMBER를 상수로 뽑아서 관리하는 것도 좋지만, 자칫 지나친 상수화는 가독성을 떨어뜨릴 수도 있는 것 같습니다
|
|
77
|
+
>
|
|
78
|
+
> — @Gyuil-Hwnag on `src/main/kotlin/model/LotteryNumber.kt`
|
|
79
|
+
|
|
80
|
+
## 얻은 교훈
|
|
81
|
+
|
|
82
|
+
- **이름의 정확성 = 도메인 의도 표현**. `Profit`보다 `ProfitRate`가 lotto에 더 맞음.
|
|
83
|
+
- **상수화도 *과잉*이 있음**. 1, 45가 *로또 번호 범위*임이 자명한 컨텍스트라면 인라인도 OK. 무조건 상수화 ≠ 좋은 코드.
|
|
84
|
+
- **"Evaluator/Calculator" 같은 행위 객체** = 인터페이스 후보. 정책 교체 가능성 시사.
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
# PR #60 — [예니] 1단계 로또
|
|
2
|
+
|
|
3
|
+
- **Reviewee:** [@JoYehyun99](https://github.com/JoYehyun99)
|
|
4
|
+
- **PR:** https://github.com/woowacourse/kotlin-lotto/pull/60
|
|
5
|
+
- **단계:** 1단계
|
|
6
|
+
- **리뷰어:** @malibinYun (말리빈)
|
|
7
|
+
- **라인 코멘트:** 43 (리뷰어 27 + 학생 16)
|
|
8
|
+
|
|
9
|
+
> *PR #75 sh1mj1*과 같은 말리빈. *비유와 시 (詩)적 표현*으로 가르치는 스타일.
|
|
10
|
+
|
|
11
|
+
## 잘한 점 (설계 관점)
|
|
12
|
+
|
|
13
|
+
- **`LottoNumber` 값 객체** — 리뷰어 칭찬: "로또 번호를 *값 객체로 만들어 주셨네요* 👍".
|
|
14
|
+
- **`LottoNumber` 캐싱** — 칭찬: "*캐싱 기능을 잘 구현해 주셨네요* 👍".
|
|
15
|
+
- **전략 패턴 분리** — 칭찬: "*전략 패턴을 활용해서 랜덤의 요소를 잘 분리해 주셨네요* 👍".
|
|
16
|
+
- **`LottoNumber` 값 객체 표현** — Lotto 안에서 *원시값 → 값 객체*.
|
|
17
|
+
|
|
18
|
+
## 못한 점 (설계 관점)
|
|
19
|
+
|
|
20
|
+
### 1. Controller에 *비교 로직* — 도메인 로직 누출
|
|
21
|
+
|
|
22
|
+
```kotlin
|
|
23
|
+
fun run() {
|
|
24
|
+
val results = lottos.map { lotto -> compareWithWinning(lotto) } // ⚠
|
|
25
|
+
}
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
리뷰어: "*로또와 당첨번호를 비교해서 결과를 만들어내는 이 로직은 도메인 로직*이네요 :) *도메인 객체에 이 역할을 부여*해 보는 건 어떨까요?"
|
|
29
|
+
|
|
30
|
+
### 2. `LotteryResult` *검증만, 행위 부재*
|
|
31
|
+
|
|
32
|
+
```kotlin
|
|
33
|
+
class LotteryResult(.) {
|
|
34
|
+
init { require(.) }
|
|
35
|
+
// ⚠ 행위 없음
|
|
36
|
+
}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
리뷰어: "*이 객체는 생성 검증을 하는 것 말고 큰 역할을 가지고 있지 않*네요. *이 객체가 맡을 만한 일이 무엇인지 찾아 이 객체에게 부여*해 보는 건 어떨까요? *이 객체에게 메시지를 던져 시킬 만한 일*이 무엇이 있을까요?"
|
|
40
|
+
|
|
41
|
+
### 3. `check~` 일관성 없는 반환
|
|
42
|
+
|
|
43
|
+
```kotlin
|
|
44
|
+
fun checkSize(): Int = numbers.size
|
|
45
|
+
fun checkDuplicate(): Boolean =.
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
리뷰어: "*check~로 시작하는데 어떤 건 숫자를 반환하고, 어떤 건 Boolean을 반환*하고 있네요! *check~ 이 메서드들을 보고 드는 생각은, 무언가 체크는 하겠구나. 정도이고, 무언가를 반환할 거라는 생각이 들지는 않았*어요. *더 명확한 이름을 지어보는 건* 어떨까요?"
|
|
49
|
+
|
|
50
|
+
### 4. *List vs Set* — 자료구조로 invariant 표현
|
|
51
|
+
|
|
52
|
+
리뷰어: "*Set을 활용해 보는 건 어떨까요*?" — PR #77 (hxeyexn)과 같은 *중복 방지 = Set*.
|
|
53
|
+
|
|
54
|
+
### 5. *문자열 파싱 시나리오*
|
|
55
|
+
|
|
56
|
+
리뷰어: "*입력 값으로 들어올 수 있는 로또 번호의 문자열 형식이 매우 많아지면 어떻게 변경*해야 할까요? *1, 2.. 뿐만 아니라, [1], [2] 혹은 one, two, 한자, 모든 언어별 숫자를 받게끔 된다면, 이 객체에서 모든 입력 문자열에 대한 검증을 수행해야 할까요*?" — 후속: "*여전히 유효한 피드백*이에요. *도메인에서 입력 값이 String이었다는 사실을 알 필요가 있을까요*?"
|
|
57
|
+
|
|
58
|
+
### 6. *로또 번호 범위*가 *여러 곳*에 — 단일 위치
|
|
59
|
+
|
|
60
|
+
리뷰어: "*로또 번호의 범위는 이곳에서 쓰고 있는데, Lotto가 가지고 있*네요! *게다가 LottoMachine에서도 사용*하고 있네요! *어디에서 가지는 게 좋을지 더 고민*해 보는 건 어떨까요?"
|
|
61
|
+
|
|
62
|
+
### 7. *도메인 안의 View 로직*
|
|
63
|
+
|
|
64
|
+
리뷰어: "*도메인 로직에 View를 그리는 로직이 들어 있*네요! *도메인 로직과 뷰 로직을 분리*해 주세요 :)"
|
|
65
|
+
|
|
66
|
+
### 8. `LottoMachine` *개수만 테스트* — 랜덤 테스트 부재
|
|
67
|
+
|
|
68
|
+
리뷰어: "개수만을 검증하는 것은 *이 객체를 완전히 테스트했다고 보기에는 어려워요*. *개발자가 제어 가능하도록, 원하는 상황에서 정확하게 원하는 반환 값이 나오는지 테스트*를 수행해야 해요. *자동차 경주 때 배웠던 랜덤 테스트를 잘 되새겨* 보시고, LottoMachine 객체를 *테스트 가능*하도록 변경해 보세요 :)"
|
|
69
|
+
|
|
70
|
+
### 10. `match`, `compare` 등 *동사*는 반환값에 따라 다른가?
|
|
71
|
+
|
|
72
|
+
학생: "*match와 compare로 수정*했습니다!"
|
|
73
|
+
|
|
74
|
+
리뷰어 (관습 인용): "*혹시 반환값에 따라 메서드 이름 내의 동사가 달라져야 하는 걸까요*? *get()을 했는데 아무것도 반환하지 않으면 굉장히 이상한 코드라는 인식*이 있겠지요! *옛날부터 내리 써 온 단어들이 몇몇* 있어요. 조금 예를 들어드리자면, *isEmpty() 같은 is\~로 시작되는 메서드는 Boolean을 반환*한답니다. 나아가서 *has\~도 대부분 Boolean을 반환*하지요. *isEmpty()를 호출했는데 String이 반환된다면 많은 개발자들이 당황*할지도 모르겠어요! match~ 하면 어떤 결과가 반환될 것 같으신가요? *저는 숫자보다는 특정 결과를 담은 Enum이 반환될 거란 생각*이 드네요. 혹은 *Boolean이 나타날 것 같아요*. *정규표현식으로부터 match를 호출하면 Boolean이 반환되는 것* 처럼요. *두 메서드의 이름을 조금만 더 고민*해 볼까요 ?_?"
|
|
75
|
+
|
|
76
|
+
### 11. *동일 LottoNumber 다른 인스턴스 생성 가능*
|
|
77
|
+
|
|
78
|
+
리뷰어: "*캐싱 기능을 잘 구현해 주셨네요* 👍 하지만 *다른 개발자가 동일한 숫자에 대해 다른 인스턴스를 생성할 수 있는 구조*에요. *어떻게 해결*해 볼 수 있을까요?" — *private constructor + 팩토리* 또는 *value class*.
|
|
79
|
+
|
|
80
|
+
### 12. *현실 비유* — *당첨티켓이 로또티켓 비교*
|
|
81
|
+
|
|
82
|
+
리뷰어: "*당첨된 로또번호 6개와, 보너스 번호를 갖고 있는 이 객체의 이름은 '로또 결과'이네요? 현실 세계를 좀 더 반영한 이름으로 바꿔보는 건* 어떨까요?" + "*당첨티켓에게 비교할 로또티켓을 주면 알아서 결과물을 반환하게 만드는*". — *현실에서 사람이 수기*로 하는 일을 *객체에게 메시지*로.
|
|
83
|
+
|
|
84
|
+
### 13. `WinningStatus` *직접 반환 X*
|
|
85
|
+
|
|
86
|
+
리뷰어: "*WinningStatus를 직접 반환하지 않은 특별한 이유*가 있었나요?_?"
|
|
87
|
+
|
|
88
|
+
### 14. *toSet 후 비교*가 *유효한 검증인가?*
|
|
89
|
+
|
|
90
|
+
```kotlin
|
|
91
|
+
require(numbers.toSet().size == numbers.size)
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
리뷰어: "*numbers는 이미 set인데, toSet을 해서 개수를 비교한들, 이 검증은 유효할까요*?" — *이미 Set이면 중복 불가*. *방어 코드의 무용성*.
|
|
95
|
+
|
|
96
|
+
### 15. *에러 메시지에 입력값 포함*
|
|
97
|
+
|
|
98
|
+
리뷰어: "*어떤 입력 값이 들어와서 발생한 예외인지 메시지에 담아보는 건* 어떨까요? *어떤 장점*이 생길까요?".
|
|
99
|
+
|
|
100
|
+
### 16. `contains operator` — *연산자 오버로딩*
|
|
101
|
+
|
|
102
|
+
리뷰어: "*contains operator를 활용*해 보는 건 어떨까요?_?" — `winningNumber in winningTicket`.
|
|
103
|
+
|
|
104
|
+
### 17. `toString` *도메인에 View 의존*
|
|
105
|
+
|
|
106
|
+
리뷰어: "*이 toString으로 도메인에서 너무 View에 의존적인 코드가 작성*되고 있는 것으로 보여요. *객체의 toString()을 사용하지 않고 View를 만들어* 주세요 :)" — *모든 PR 공통* 패턴.
|
|
107
|
+
|
|
108
|
+
### 18. `List() { }` 가짜 생성자
|
|
109
|
+
|
|
110
|
+
리뷰어: "*List() { } 가짜 생성자를 활용해 보는 건* 어떨까요? 혹은, *IntRange를 활용해서 함수 체이닝을 활용*해 보는 건 어떨까요? *mutableList를 만들고, 반복문으로 해당 컬렉션을 채우는 방법 대신*에 위 방법을 고민해 보세요 :)". idiom.
|
|
111
|
+
|
|
112
|
+
### 19. *Lotto 가변 생성* `Lotto(1, 2, 3, 4, 5, 6)`
|
|
113
|
+
|
|
114
|
+
리뷰어: "아래처럼 *생성할 수 있게 다양한 방법을 제공*해 보는 건 어떨까요? `val lotto = Lotto(1, 2, 3, 4, 5, 6)`. *테스트 코드를 쉽게 작성할 수 있을 뿐만 아니라, 다른 개발자가 Lotto 객체를 생성할 수 있는 여러 방법을 제공해 편리함을 높일 수* 있겠어요 :)" — `vararg Int` 팩토리.
|
|
115
|
+
|
|
116
|
+
### 20. *test fixture* — jojoldu 블로그 참고
|
|
117
|
+
|
|
118
|
+
리뷰어: "*테스트를 실행하기 전 준비하는 데이터들에 대해 '테스트 픽스처'라고 부른답니다*. 이 테스트 픽스처에 대한 *좋은 글을 공유드릴게요* :) https://jojoldu.tistory.com/611" — 우테코 공통 자료.
|
|
119
|
+
|
|
120
|
+
### 21. *ParameterizedTest *두 경계값 한 함수*
|
|
121
|
+
|
|
122
|
+
```kotlin
|
|
123
|
+
@ParameterizedTest
|
|
124
|
+
@ValueSource(strings = ["1,2,3,4,5", "1,2,3,4,5,6,7"]) // 5개 + 7개
|
|
125
|
+
fun.
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
리뷰어: "*꼭 ParameterizedTest로 두 경우를 한 메서드에서 검증해야 하는 항목이었을까요*? 테스트 코드는 *최대한 직관적으로 읽히는 게 중요*해요. `input.split(", ").map`처럼, *머릿속에서 계산을 해 보아야 하는 부분은 읽는 사람으로 하여금 잠시 읽기를 멈추게* 되어요. *그러다가 데이터가 무엇이었는지 다시 위로 돌아가 읽어야 하는 경우*가 생길 수 있어요. 이런 *사소한 것들이 테스트 가독성을 해치는 요소*라 생각해요 :) 이 경우는 *5개 혹은 7개 하나만으로도 충분한 테스트*를 할 수 있을 거라 생각해요. *두 경계값을 모두 테스트해야 한다면, 테스트를 두 개로 나눠*보는 건 어떨까요?" — PR #61 (호두)와 같은 *명세 테스트* 강조.
|
|
129
|
+
|
|
130
|
+
## 리뷰어 의견 요지
|
|
131
|
+
|
|
132
|
+
- **Controller의 *비교 로직* → 도메인**.
|
|
133
|
+
- **검증만 객체 = *행위 부여***.
|
|
134
|
+
- **`check~` *일관성*** — 동사가 반환값 시사.
|
|
135
|
+
- **`Set` *중복 방지 invariant***.
|
|
136
|
+
- ***문자열 다국어 시나리오*** — 도메인 = 변환된 입력.
|
|
137
|
+
- **상수 *단일 위치***.
|
|
138
|
+
- **도메인 안 View 로직 제거**.
|
|
139
|
+
- **랜덤 테스트 *제어 가능*하게**.
|
|
140
|
+
- **`is~`/`has~` = Boolean, `match~` = Boolean/Enum 관습**.
|
|
141
|
+
- **`LottoNumber` *동일 인스턴스 강제*** — private constructor + 팩토리.
|
|
142
|
+
- **에러 메시지에 *입력값 포함***.
|
|
143
|
+
- **`in` operator** ( 강사).
|
|
144
|
+
- **`List() { }` 가짜 생성자**.
|
|
145
|
+
- **`vararg` 팩토리로 테스트 편의**.
|
|
146
|
+
- **test fixture *jojoldu 블로그***.
|
|
147
|
+
- **`ParameterizedTest` *두 경계값 = 두 테스트***.
|
|
148
|
+
|
|
149
|
+
- **대표 인용:**
|
|
150
|
+
|
|
151
|
+
> 현실세계에서는 사람이 수기로 비교해서 결과를 계산하지만, 프로그래밍 세계에서는 조금 마법을 부려서, *당첨티켓에게 비교할 로또티켓을 주면 알아서 결과물을 반환하게 만드는 신기한 프로그래밍 세계*를 접해 볼 수 있어요.
|
|
152
|
+
|
|
153
|
+
> 머릿속에서 *계산을 해 보아야 하는 부분은 읽는 사람으로 하여금 잠시 읽기를 멈추게* 되어요.
|
|
154
|
+
> — @malibinYun on `src/test/kotlin/lotto/domain/LottoTest.kt`
|
|
155
|
+
|
|
156
|
+
> 다른 개발자가 동일한 숫자에 대해 *다른 인스턴스를 생성할 수 있는 구조*에요. 어떻게 해결해 볼 수 있을까요?
|
|
157
|
+
> — @malibinYun on `src/main/kotlin/domain/LottoNumber.kt`
|
|
158
|
+
|
|
159
|
+
## 얻은 교훈
|
|
160
|
+
|
|
161
|
+
- **Controller *비교 로직 = 도메인 침범*** — *lotto.match(winningTicket)*이 자연.
|
|
162
|
+
- ***검증만 객체 = 빈 껍데기*** — *행위 부여*가 객체의 본질. `init { require }` 만이면 *valuobject도 아니고 wrapper*.
|
|
163
|
+
- **`check~` 일관성 없음** — *동사가 반환값 관습*에 맞아야. `size` (Int), `hasDuplicate` (Boolean), `validate` (예외/Unit).
|
|
164
|
+
- **`Set` 자료구조 = invariant 표현** — *중복 불가*는 *검증*보다 *타입*.
|
|
165
|
+
- **다국어 문자열 시나리오** — *도메인은 List<Int> 받기*. *String 파싱*은 *View*.
|
|
166
|
+
- **상수 *단일 위치*** — *Lotto + LottoMachine 둘 다*면 *변경 누락*.
|
|
167
|
+
- **도메인 안 View 로직 = 모든 PR 공통 안티**.
|
|
168
|
+
- **랜덤 테스트 *제어 가능*하게** — *Random 외부 주입*.
|
|
169
|
+
- **`get`, `is~`, `has~`, `match~` *관습 어휘*** — Boolean/Enum/특정 반환에 *내장 의미*.
|
|
170
|
+
- **`LottoNumber` *동일 인스턴스 강제*** — `private constructor + Map<Int, LottoNumber>` 캐싱. 외부에서 *new*를 못 만들도록.
|
|
171
|
+
- **에러 메시지에 *입력값 포함*** — *로그 수집 시대*에 유일한 데이터 보존.
|
|
172
|
+
- **`contains operator`** — `winningNumber in lotto`. 도메인 어휘를 *언어 표현*으로 매핑.
|
|
173
|
+
- **`List(n) { gen() }` 가짜 생성자** — *MutableList + repeat*보다 *불변*.
|
|
174
|
+
- **`vararg Lotto(1,2,3,4,5,6)` 팩토리** — 테스트 편의 + *다양한 생성 경로*.
|
|
175
|
+
- **test fixture *jojoldu 블로그*** — *공통 데이터 분리*. *지역성*과 *재사용*의 균형 (PR #21 *MethodSource* 같이 봐야).
|
|
176
|
+
- **`ParameterizedTest` *경계값 분리*** — *5개*와 *7개*는 *다른 명세*. *한 함수*로 묶으면 *어느 입력이 어느 결과*인지 *지연 계산*.
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# PR #96 — [예니] 로또 2단계
|
|
2
|
+
|
|
3
|
+
- **Reviewee:** [@JoYehyun99](https://github.com/JoYehyun99)
|
|
4
|
+
- **PR:** https://github.com/woowacourse/kotlin-lotto/pull/96
|
|
5
|
+
- **단계:** 2단계
|
|
6
|
+
- **리뷰어:** @malibinYun
|
|
7
|
+
- **라인 코멘트:** 49
|
|
8
|
+
|
|
9
|
+
## 잘한 점
|
|
10
|
+
|
|
11
|
+
- **랜덤 요소 분리 (Strategy)**.
|
|
12
|
+
- **LottoNumber 캐싱 (flyweight 적용)** — 칭찬.
|
|
13
|
+
- **PurchaseAmount + 팩토리 메서드 + 생성자 둘 다**.
|
|
14
|
+
|
|
15
|
+
## 못한 점 + 핵심 지적
|
|
16
|
+
|
|
17
|
+
### 1. `in` → `contains` 변경 이유?
|
|
18
|
+
|
|
19
|
+
```kotlin
|
|
20
|
+
fun hasNumber(n: LottoNumber): Boolean = numbers.contains(n) // 이전엔 `n in numbers`
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
> in 연산자에서 contains 함수로 변경한 이유가 무엇이었나요?
|
|
24
|
+
|
|
25
|
+
→ Kotlin에서 둘은 같음. *왜* 변경했는지가 더 중요.
|
|
26
|
+
|
|
27
|
+
### 2. 자동/수동 발급 로직 중복
|
|
28
|
+
|
|
29
|
+
```kotlin
|
|
30
|
+
fun generateManual(numbers: List<Int>): Lotto = Lotto(numbers.map(::LottoNumber))
|
|
31
|
+
fun generateAuto(): Lotto = Lotto(randomNumbers().map(::LottoNumber))
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
> 자동 발급 로직에서 수동 발급 로직을 재활용해보는 건 어떨까요?
|
|
35
|
+
|
|
36
|
+
→ 자동 = "랜덤 번호로 수동 생성"으로 재해석.
|
|
37
|
+
|
|
38
|
+
### 3. LottoNumber 캐싱 검증 테스트 부재
|
|
39
|
+
|
|
40
|
+
> 늘 같은 인스턴스가 실제로 반환되고 있는지 테스트 코드로 검증해보는 건 어떨까요?
|
|
41
|
+
|
|
42
|
+
→ `assertThat(LottoNumber.of(1)).isSameAs(LottoNumber.of(1))`.
|
|
43
|
+
|
|
44
|
+
### 4. 생성자 + 팩토리 메서드 둘 다 — 의도?
|
|
45
|
+
|
|
46
|
+
```kotlin
|
|
47
|
+
class PurchaseAmount(val value: Int) {
|
|
48
|
+
init { require(.) }
|
|
49
|
+
companion object {
|
|
50
|
+
fun of(input: String): PurchaseAmount {
|
|
51
|
+
require(.)
|
|
52
|
+
return PurchaseAmount(input.toInt())
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
> 생성자를 사용하는 것과 팩토리 메서드를 사용하는 것 두 가지 모두 구현한 이유가 무엇일까요? 검증 로직도 굉장히 비슷하네요!
|
|
59
|
+
|
|
60
|
+
→ 둘 다 노출 = 호출자 혼란. 하나로 선택.
|
|
61
|
+
|
|
62
|
+
### 5. View가 LottoNumber → Int 타입 변경
|
|
63
|
+
|
|
64
|
+
> 요기에서 타입 반환을 LottoNumber -> Int로 바꾸게 된 생각의 변화가 궁금해요!
|
|
65
|
+
|
|
66
|
+
## 얻은 교훈
|
|
67
|
+
|
|
68
|
+
- **자동 = 랜덤 + 수동의 합성**. 재활용으로 코드 줄이기.
|
|
69
|
+
- **flyweight 캐싱 검증** — `isSameAs` (참조 동일성)로 캐시 동작 확인.
|
|
70
|
+
- **생성자 vs 팩토리 메서드** — 둘 다 노출 X. 하나만.
|
|
71
|
+
- **변경 이유 PR에 명시** — 리뷰어가 왜 변경했는지 묻는 패턴이 반복.
|