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,444 @@
|
|
|
1
|
+
# PR #146 — [블랙잭 2단계] 채넛 미션
|
|
2
|
+
|
|
3
|
+
- **Reviewee:** [@yrsel](https://github.com/yrsel)
|
|
4
|
+
- **PR:** https://github.com/woowacourse/kotlin-blackjack/pull/146
|
|
5
|
+
- **단계:** 2단계 (베팅 / 수익률 / 블랙잭 1.5배)
|
|
6
|
+
- **리뷰어:** @Gyuil-Hwnag (두루)
|
|
7
|
+
- **라인 코멘트:** 24 스레드 / 43 코멘트 — *typealias 자가 학습 + Demeter 깊이 토론 + value class 학습* 풍부
|
|
8
|
+
|
|
9
|
+
## 잘한 점 (설계 관점)
|
|
10
|
+
|
|
11
|
+
- **`typealias Participants` / `typealias GameFactor` 자가 학습 + 트레이드오프 명시** — 두루 메타 질문 *"typealias 사용하시게 된 이유와 어떠한 장단점 및 특징이 있으셨을지 궁금합니다"* + 학생 자가 답변: *"`typealias` 사용하게 된 이유는 반환값으로 여러 데이터를 한 번에 넘겨야 하는 상황이 있었는데 그 외 다른 곳에서는 사용할 일이 없어서 클래스를 만드는 것보다는 `typealias`를 선택하는 것이 효율적으로 생각되었습니다. 장점으로는 클래스를 생성하지 않아도 이름으로 의미를 전달할 수 있다고 생각되었고 ... 단점으로는 typealias가 어떤 데이터를 담고 있는 지 명시해놓은 부분을 확인해야만 알 수 있다는 점과 클래스인지 typealias 인지 이름만 봤을 때 판단하기 어려워 혼란을 줄 수 있을 것 같습니다."*. **Kotlin typealias 자가 학습 + 트레이드오프 양면 명시 모범**. 두루 자가 답변: *"`typealias`에 대한 의견 정말 좋습니다👍 저는 사실 `typealias`를 잘 사용하지는 않긴 합니다😅"*. **MCP 룰 후보 — `typealias-vs-class`**.
|
|
12
|
+
- **`Score @JvmInline value class + Comparable<Score>`** — *operator compareTo* 자동 구현. *`Score < other`* 자연 표현. PR #136 (밀러 2단계) 의 *Score data class + compareTo* 와 같은 결의 *value class 트레이드오프*.
|
|
13
|
+
- **`Money @JvmInline value class + private constructor + 5 factory (`from / toBlackjackMoney / toWinMoney / toDrawMoney / toLoseMoney / toDealerMoney`)** — *팩토리 패턴 + 도메인 변환 의도 명시*. *원시 박싱 없음 + 타입 안전 + 도메인 어휘*. PR #90·#131·#132·#136·#49 와 같은 결의 *value class*.
|
|
14
|
+
- **`GameStatus.of(score, cardCount)` 정적 팩토리** — *블랙잭 룰 (2장 + 21 점)* 정확 분기. *factory + enum 응집*. PR #131·#90 와 같은 결.
|
|
15
|
+
- **`Dealer.isAvailDrawCard() = hand.score.isDrawableCardByDealer()`** — *Dealer 자기 룰 + Score 메시지*. 다만 *Score 가 *Dealer 룰* 알고 있음* — 못한 점 §3 참고.
|
|
16
|
+
- **`BlackjackInput` interface 도입** — 두루 자가 칭찬: *"Interface의 생성 좋습니다~👍"*. PR #131·#133·#136 와 같은 결의 *DIP*.
|
|
17
|
+
- **YAGNI 자가 학습** — 두루 진단 *"해당 함수는 `targetNumber`에 무조건 ACE만 들어오는군요"* + 학생 자가 인용: *"확장성을 고려해 만들다보니 생긴 코드였습니다. > YAGNI 프로그래머가 필요하다고 간주할 때까지 기능을 추가하지 않는 것이 좋다는 XP의 원칙이다. ... 앞으로는 위의 규칙에 따라 필요한 기능만을 구현하고 필요하게 되면 리팩터링을 진행해보겠습니다."*. **YAGNI 원칙 자가 학습 + 인용 모범**. PR #136·#137·#88 와 같은 결.
|
|
18
|
+
- **Deck factory 메서드 + 카드 직접 초기화 자가 후속** — 페로로 진단 (이전 PR 인용) + 자가 반영.
|
|
19
|
+
- **`distribute → draw` 메서드명 자가 반영** — 두루 진단 *"`distribute`라는 네이밍이 살짝 눈에 걸리기는 하군요"* + 학생 자가 반영: *"`gameManager.distributeInitialCardWithCount()` vs `gameManager.drawInitialCardWithCount()` 게임 매니저 입장에서 생각해서 분배해준다는 느낌이었어서 `distribute` 라고 명명해봤는데 조금 어색했군요😅 카드를 뽑는다는 의미가 포함되면 조금 더 이해하기 쉬울 것 같아서 `draw` 로 변경했습니다."*. PR #133·#88·#137 와 같은 결의 *naming = 책임 표현*.
|
|
20
|
+
- **`Money.toBlackjackMoney(money) → money.toBlackjackMoney()` Demeter 자가 학습** — 두루 진단 + 학생 자가 답변: *"`Money.toBlackjackMoney(player.money)` : Money 는 Helper 객체인가?, Player의 money를 받아서 blackjack 인 경우 이윤을 알려주나 보구나"* + *"depth가 깊은 것에 대한 생각을 다시 해보게 되었고 depth 깊이보다는 의도를 명확히 표현할 수 있는지가 더 중요하다고 느꼈습니다. 이번 미션에서는 헬퍼 역할보다는 도메인 역할을 기대하고 만들었기에 Money 객체에게 메시지를 전송하는 방식을 선택해보려고 합니다!"*. **Demeter vs 의도 표현 트레이드오프 자가 학습 모범**.
|
|
21
|
+
- **`data class` vs `class` + `toString` 토론** — 두루 메타 질문 + 학생 자가 답변: *"`data class`는 `toString()`, `equals()`, `hashCode()`, `componentN()`, `copy()` 메서드를 제공해주는 이점이 있습니다. 해당 메서드들이 필요한 경우에 `data class`를 선택할 것 같습니다. 그 중 `copy()` 메서드의 경우 List 와 같은 자료구조의 제네릭 타입이 Card, Member, Person 등 참조형일 경우 원소들이 얕은 복사가 진행되는 것으로 알고 있어 사용에 유의해야 할 것 같습니다. View에서 활용할 때 클래스 내에 오버라이딩 된 toString()을 사용한다면 View를 변경하고 싶을 때에도 도메인 코드까지 확인해야 한다는 문제와 여러 군데에서 출력을 위해 호출하지만 출력 형태가 다를 경우 toString()이 어떤 출력 형태를 반환하는 지 알기 어려워 혼란을 줄 수 있을 것 같습니다. 그렇기에 제시해준 방법처럼 Extension 클래스를 생성해서 출력형식을 관리하거나 View 클래스내에서 출력을 위한 형태로 변환해줄 것 같습니다."*. **Kotlin 어휘 + toString trade-off 자가 학습 모범**. PR #88·#137·#90 와 같은 결.
|
|
22
|
+
- **`toUi()` Extension 분리 자가 반영** — 두루 진단: *"toUi() 라는 Extension 부분에 대한 파일을 분리하여 사용한다면, 다른 OutputView에서도 사용을 해볼 수 있겠군요!"* + 학생 자가 반영 (커밋 `55276a`). *Kotlin Extension function 활용 모범*.
|
|
23
|
+
|
|
24
|
+
## 못한 점 (설계 관점)
|
|
25
|
+
|
|
26
|
+
### 1. `typealias Participants = Pair<Dealer, List<Player>>` + `typealias GameFactor = Triple<...>` — *현실적 의미 vs 명시성 트레이드오프*
|
|
27
|
+
|
|
28
|
+
```kotlin
|
|
29
|
+
typealias Participants = Pair<Dealer, List<Player>>
|
|
30
|
+
typealias GameFactor = Triple<Dealer, List<Player>, GameManager>
|
|
31
|
+
|
|
32
|
+
class BlackjackGame(...) {
|
|
33
|
+
fun start() {
|
|
34
|
+
val (dealer, players, gameManager) = gameReady()
|
|
35
|
+
...
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
private fun gameReady(): GameFactor { ... }
|
|
39
|
+
private fun initParticipants(): Participants { ... }
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
두루 자가 의견: *"만약 사용한다고 하면, `typealias Participants = Pair<Dealer, List<Player>>`까지는 그래도 어떤 것을 반환하는지 조금은 알 수 있어서 활용을 해볼 수 있을 것 같은데, `typealias GameFactor = Triple<Dealer, List<Player>, GameManager>`형태는 지양을 해볼 것 같긴 합니다만, 현재처럼 구현이 길지 않을 때는 사용하는 것도 좋아 보이네요ㅎㅎ💯"*
|
|
44
|
+
|
|
45
|
+
→ **`typealias` 가 *Pair/Triple* 같은 *익명 묶음에 의미 부여* 시 유용**. *3+ 멤버* 면 *전용 data class* 가 정공. *`GameFactor = Triple<Dealer, List<Player>, GameManager>`* 는 *3 멤버 + 의미 모호* — *클래스 분리* 가 자연. PR #132 (환노 2단계) 의 *Map<X,X> 지양* 와 같은 결의 *익명 컬렉션 회피*.
|
|
46
|
+
|
|
47
|
+
### 2. `INITIAL_HAND_OUT_CARD_COUNT` Deck 상수 위치 — *룰 위치 모호*
|
|
48
|
+
|
|
49
|
+
```kotlin
|
|
50
|
+
gameManager.drawInitialCardWithCount(INITIAL_HAND_OUT_CARD_COUNT)
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
두루 메타 질문: *"`INITIAL_HAND_OUT_CARD_COUNT`는 Deck 에서 상수로 선언을 해두신 이유가 궁금합니다"*
|
|
54
|
+
|
|
55
|
+
학생 자가 답변: *"블랙잭 게임의 규칙이 처음에 2장이 아닌 1장 또는 3장 등 다양하게 변경될 가능성을 고려해서 인자로 넘겨주었습니다. 불필요한 유지보수 포인트를 만든 것 같다는 생각이 들기는 하네요..😅"*
|
|
56
|
+
|
|
57
|
+
→ **블랙잭 룰 = "초기 2장 분배"** = *블랙잭 도메인 룰*. *Deck 상수 위치 = Deck 이 분배 룰 알고 있음* — *룰 위치 모호*. *BlackjackGame 또는 GameManager companion* 이 자연. *YAGNI* 학생 자가 인식.
|
|
58
|
+
|
|
59
|
+
### 3. `Score.isDrawableCardByDealer(): Boolean = number < 17` — *Score 가 Dealer 룰 알고 있음*
|
|
60
|
+
|
|
61
|
+
```kotlin
|
|
62
|
+
@JvmInline
|
|
63
|
+
value class Score private constructor(val number: Int) : Comparable<Score> {
|
|
64
|
+
fun isBust(): Boolean = number > BUST_NUMBER
|
|
65
|
+
fun isBlackjackNumber(): Boolean = number == BUST_NUMBER
|
|
66
|
+
fun isDrawableCardByDealer(): Boolean = number < DEALER_DRAW_CARD_MINIMUM_SCORE // ⚠ Dealer 룰
|
|
67
|
+
...
|
|
68
|
+
companion object {
|
|
69
|
+
private const val ADJUST_ACE_NUMBER = 10
|
|
70
|
+
private const val DEALER_DRAW_CARD_MINIMUM_SCORE = 17
|
|
71
|
+
const val BUST_NUMBER = 21
|
|
72
|
+
...
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
→ **`Score` 가 *Dealer 의 17 룰* 보유**. *Score = 일반 점수 객체*. *`isDrawableCardByDealer` = *Dealer 자기 룰* — *Score 누수***. *Dealer.canDraw() = score.number < 17* 처럼 *Dealer 안에서 직접*이 *룰 위치 정합*. PR #131·#136·#108 (시아) / PR #137·#90 와 같은 결의 *Score 가 도메인 룰 알기*.
|
|
78
|
+
|
|
79
|
+
### 4. `Score.optimizedSum` 의 `while (countOfAce-- > 0)` — Kotlin 어휘 미숙
|
|
80
|
+
|
|
81
|
+
```kotlin
|
|
82
|
+
fun optimizedSum(cards: List<Card>): Score {
|
|
83
|
+
var totalScore: Score = sum(cards)
|
|
84
|
+
var countOfAce = countOfAce(cards)
|
|
85
|
+
while (countOfAce-- > 0) {
|
|
86
|
+
if (totalScore.number > BUST_NUMBER) totalScore -= from(ADJUST_ACE_NUMBER)
|
|
87
|
+
}
|
|
88
|
+
return totalScore
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
→ **`countOfAce-- > 0` = Java/C 어휘**. *Kotlin = `repeat(countOfAce)` 또는 `for (i in 1..countOfAce)`* 가 *어휘 정공*. PR #58·#93·#108·#137 와 같은 결.
|
|
93
|
+
|
|
94
|
+
또한 *while 안에 if + break 없음* — *aceCount 모두 -10 시도*. *Bust 도달 후 더 차감 시 음수 점수 가능성* — *break 가 *Ace 1 도달 시 종료* 의도*. *현재 코드*는 *Bust 시 매 Ace -10 + Bust 아니면 그대로* — *Bust 후 점수가 0 또는 음수 가능*.
|
|
95
|
+
|
|
96
|
+
*예: A♠ A♥ A♣ 5♦ = base 4 (Ace 1×3 + 5) → optimizedSum: Bust 아니므로 -10 안 함 → score = 4*. *Ace 11 사용 안 함*.
|
|
97
|
+
*하지만 sum 메서드가 Ace.score = 1* 라 *base 4 = 정확*. *Ace 11 의도면 +10 보너스 적용 별도 필요*.
|
|
98
|
+
|
|
99
|
+
→ **현재 `optimizedSum` 이 *Ace 1 기본 + Bust 시 -10 반복*** 패턴. *문제* — *Ace 1 기본이면 Bust 아닌 sum 에 +10 보너스 안 함*. *블랙잭 룰 = Ace 11 우선 + Bust 시 1로 변환*. 코드는 *Ace 1 우선 + Bust 시 (이미 Bust 인 케이스만) -10*. **룰 부정확 (Ace 보너스 +10 누락)**.
|
|
100
|
+
|
|
101
|
+
*수정* = `optimizedSum`이 *Ace 별 11 시도 + Bust 시 1로* 또는 *base sum + Ace 11 보너스 +10 if ≤21*. PR #128·#114·#125·#108·#131·#136·#137·#41 와 같은 결의 표준 패턴 미적용.
|
|
102
|
+
|
|
103
|
+
### 5. `Money` companion object 의 *5 factory + plus operator* — *Money 가 *Helper 객체* 의문 (학생 자가 인용)*
|
|
104
|
+
|
|
105
|
+
```kotlin
|
|
106
|
+
@JvmInline
|
|
107
|
+
value class Money private constructor(val amount: Long) {
|
|
108
|
+
companion object {
|
|
109
|
+
fun from(amount: Long): Money = Money(amount)
|
|
110
|
+
fun toBlackjackMoney(money: Money): Money = Money((money.amount * 1.5).toLong())
|
|
111
|
+
fun toWinMoney(money: Money): Money = Money(money.amount)
|
|
112
|
+
fun toDrawMoney(): Money = Money(0L)
|
|
113
|
+
fun toLoseMoney(money: Money): Money = Money(money.amount * -1)
|
|
114
|
+
fun toDealerMoney(playersProfitSum: Money): Money = Money(playersProfitSum.amount * -1)
|
|
115
|
+
|
|
116
|
+
operator fun Money.plus(other: Money): Money = Money(amount + other.amount)
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
학생 자가 답변 (Demeter 토론): *"`Money.toBlackjackMoney(player.money)` : Money 는 Helper 객체인가?, Player의 money를 받아서 blackjack 인 경우 이윤을 알려주나 보구나"* — **자가 인식**.
|
|
122
|
+
|
|
123
|
+
→ **`Money` companion 의 5 변환 factory + plus** = *Helper 객체 측면 강함*. *도메인 객체 = 자기 상태 + 메시지*. *현재 `Money` 가 *변환 헬퍼*에 가까움*. *`money.toBlackjack(): Money` 같은 *멤버 메서드*가 *Tell-Don't-Ask 정공*. *operator plus* 만 *멤버 메서드* — 비대칭.
|
|
124
|
+
|
|
125
|
+
학생 자가 후속 의도 = *`Money.toBlackjackMoney → money.toBlackjackMoney()` 자가 변경* (Demeter + 도메인 객체 의도).
|
|
126
|
+
|
|
127
|
+
### 6. `Money.operator fun Money.plus(other: Money)` companion object 안 — *Kotlin 어휘 어색*
|
|
128
|
+
|
|
129
|
+
```kotlin
|
|
130
|
+
companion object {
|
|
131
|
+
...
|
|
132
|
+
operator fun Money.plus(other: Money): Money = Money(amount + other.amount)
|
|
133
|
+
}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
→ **`operator fun Money.plus` = extension function on Money** — *companion 안에 정의*. *Kotlin Extension function* 패턴이지만 *companion 위치*가 *함수 접근*에 제한 — *호출자가 import Money.Companion.plus* 필요. *멤버 함수 `operator fun plus(other: Money): Money`* 가 *간결*. PR #133·#90·#137 와 같은 결의 *operator 멤버*.
|
|
137
|
+
|
|
138
|
+
### 7. `Hand` 가 *외부 노출 (`val hand = Hand()`)* — Participant 책임 모호
|
|
139
|
+
|
|
140
|
+
```kotlin
|
|
141
|
+
open class Participant(val name: String) {
|
|
142
|
+
val hand = Hand() // ⚠ public
|
|
143
|
+
|
|
144
|
+
fun addCard(card: Card) = hand.addCard(card)
|
|
145
|
+
fun isBust(): Boolean = GameJudge.judge(hand) == GameStatus.BUST
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
두루 진단 (Participant.kt:10 — 미해결): *"흠~ 현재와 같은 구조에서는 해당 방법밖에는 없을 것 같기는 하겠네요...🥲 아니면 한가지 방법이 있을 수도 있겠군요! `Participant 에서 Hand()를 상속받는 형태`로요"*
|
|
150
|
+
|
|
151
|
+
→ **`Participant.hand` 외부 노출**. *호출자가 `participant.hand.cards`* 접근 가능. *Demeter 위반 표면*. *Participant.cards() / Participant.score()* 위임 메서드가 정공. PR #88·#133·#108·#137 와 같은 결.
|
|
152
|
+
|
|
153
|
+
*두루 권고 = Participant 가 Hand 상속* — *카드 메시지 = Participant 자기 메시지*. *상속 vs 위임* 트레이드오프 — *Composition over Inheritance* 와 *상속의 직접성* 의 균형.
|
|
154
|
+
|
|
155
|
+
### 8. `Dealer.isBlackjack()` + `Participant.isBust()` 두 메서드 — *Participant 다형성 부재 신호*
|
|
156
|
+
|
|
157
|
+
```kotlin
|
|
158
|
+
open class Participant(val name: String) {
|
|
159
|
+
...
|
|
160
|
+
fun isBust(): Boolean = GameJudge.judge(hand) == GameStatus.BUST
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
class Dealer(name: String = DEALER_NAME) : Participant(name) {
|
|
164
|
+
fun isBlackjack(): Boolean = GameJudge.judge(hand) == BLACKJACK
|
|
165
|
+
fun isAvailDrawCard(): Boolean = hand.score.isDrawableCardByDealer()
|
|
166
|
+
...
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
class Player(name: String, val money: Money) : Participant(name)
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
→ **`isBlackjack` Dealer만 + `isBust` Participant 공통 + `isAvailDrawCard` Dealer만**. *Player.isAvailDrawCard 부재* — *외부 람다 (`playerDrawDecision`) 의존*. *Player.canHit() = !isBust && needsMore (입력) 다형성*이 *PR #49·#108·#132 등 와 같은 결*. 현재는 *Player 다형성 메서드 부재*.
|
|
173
|
+
|
|
174
|
+
또한 *`open class Participant`* — *abstract 가 아닌 open*. *PR #131·#132·#136·#49 의 abstract Participant* 와 *반대 트레이드오프*.
|
|
175
|
+
|
|
176
|
+
### 9. `ProfitCalculator object` — *정적 헬퍼 = Tell-Don't-Ask 미달 (자가 인식 + 후속 반영)*
|
|
177
|
+
|
|
178
|
+
```kotlin
|
|
179
|
+
object ProfitCalculator {
|
|
180
|
+
fun calculateProfit(dealer: Dealer, player: Player): Money =
|
|
181
|
+
getMoneyByGameStatusOrNull(dealer, player) ?: getMoneyByCompareToScore(dealer, player)
|
|
182
|
+
...
|
|
183
|
+
}
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
→ **`ProfitCalculator object` = 정적 헬퍼**. *Player.calculateProfit(dealer): Money* 같은 *Player 메시지*가 *Tell-Don't-Ask*. PR #131·#136·#132·#49 와 같은 결의 *정적 헬퍼 회피*.
|
|
187
|
+
|
|
188
|
+
학생 자가 학습 (Score.kt:9 토론): *"-> 해당 부분을 바꿔보니 util 기능에 가깝다고 느껴졌던 ScoreCalculator 대신 도메인 객체로 관리할 수 있다는 점이 유용한 것 같습니다."* — *Score → 도메인 객체 자가 인식 + Profit 도 같은 결로 변환 의도*.
|
|
189
|
+
|
|
190
|
+
### 10. `BlackjackGame.dealerDrawCards` — *한 번만 draw + return Boolean*
|
|
191
|
+
|
|
192
|
+
```kotlin
|
|
193
|
+
private fun dealerDrawCards(gameManager: GameManager) {
|
|
194
|
+
val isDraw = gameManager.isDrawCardBasedOnDealer()
|
|
195
|
+
outputView.printDealerHandStatus(isDraw)
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// GameManager
|
|
199
|
+
fun isDrawCardBasedOnDealer(): Boolean {
|
|
200
|
+
if (dealer.isAvailDrawCard()) {
|
|
201
|
+
drawCard(dealer)
|
|
202
|
+
return true
|
|
203
|
+
}
|
|
204
|
+
return false
|
|
205
|
+
}
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
→ **`isDrawCardBasedOnDealer()` 호출 한 번 = Dealer 카드 1장 받거나 안 받음**. *Dealer 룰 = 17 이상까지 hit* = *호출자가 반복 호출 강제*. *Tell-Don't-Ask 미달 (PR #152 모찌 와 같은 결)*. *`dealer.drawUntilStand(deck)`* 같은 *Dealer 자기 메시지*가 정공. 또는 *while (dealer.canDraw()) { dealer.draw(deck) }* 내부 응집.
|
|
209
|
+
|
|
210
|
+
`BlackjackGame.dealerDrawCards` 가 *Dealer 카드 1장 + 메시지 출력* — *Dealer 가 17 도달 시 호출 종료* 없음. *현재 코드 = 단 1회 호출* — *룰 부정확*. 실제로는 *Dealer 카드 한 번만 받을 가능성 (16→17 도달)* 인데 *16 → 13 (5 카드 인출 후)* 같은 *여러 번 hit 케이스 미반영*.
|
|
211
|
+
|
|
212
|
+
다만 *호출자가 매번 호출 반복*하면 동작. *현재 BlackjackGame.dealerDrawCards = 한 번만 호출* — *룰 부정확 가능성*. **루프 부재**.
|
|
213
|
+
|
|
214
|
+
### 11. `Player.money: Money` 외부 노출 — *베팅금 외부 변경 가능성*
|
|
215
|
+
|
|
216
|
+
```kotlin
|
|
217
|
+
class Player(name: String, val money: Money) : Participant(name)
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
→ **`val money: Money` 외부 노출**. *val* 이라 *교체 불가*. *Money = value class + immutable* — *변경 불가*. *PR #58 의 외부 가변 변경 우려* 와 *반대 결* (Money 자체 불변).
|
|
221
|
+
|
|
222
|
+
학생 자가 답변 (Money.kt 토론): *"Money 객체가 Player의 생성자로 있어야하는 이유는 알맞은 위치를 찾지 못해 그렇게 구현했던 것 같습니다. 현재 Player는 부모인 Participant 프로퍼티까지 생각한다면 4개의 인스턴스를 갖게되어 요구사항도 만족시키지 못하게 되었습니다.😟 사실 Player와 Money를 상태를 갖고 있는 PlayerTable 의 이름의 객체를 생성했었습니다. 현재 구조에서 Player 역할이 모두 PlayerTable을 통해서 수행되어야 했기에 많은 부분이 변경되다보니 잘못된 설계로 인해 변경부분이 많다고 생각되어 임시로 Player 프로퍼티로 갖게 되었습니다. Player와 Money를 감싸는 Wrapper가 있다면 인스턴스 개수에 대한 요구조건은 만족할 수 있겠으나 List<Player>를 모두 List<Wrapper> 와 같이 변경해야하다보니 더 좋은 방법이 있을 지 고민중입니다."*
|
|
223
|
+
|
|
224
|
+
→ **3 변수 제약 토론 = 학생 자가 회의 + 임시 결정**. *Participant.name + Participant.hand + Player.money = 3 변수*. *제약 위반*. *PlayerTable Wrapper 시도 후 잘못된 설계 자가 인식 + 후퇴*. **3 변수 제약 = 연습 도구 인식 + 학생/리뷰어 양방향 학습** (PR #133·#88·#132·#136·#41·#49 와 같은 결).
|
|
225
|
+
|
|
226
|
+
### 12. `GameStatus enum` 의 `STAY` 상태 — *Stay 자체 vs 진행 상태*
|
|
227
|
+
|
|
228
|
+
```kotlin
|
|
229
|
+
enum class GameStatus {
|
|
230
|
+
BLACKJACK,
|
|
231
|
+
BUST,
|
|
232
|
+
STAY,
|
|
233
|
+
;
|
|
234
|
+
|
|
235
|
+
companion object {
|
|
236
|
+
fun of(score: Score, cardCount: Int): GameStatus {
|
|
237
|
+
if (score.isBlackjackNumber() && cardCount == INITIAL_HAND_OUT_CARD_COUNT) return BLACKJACK
|
|
238
|
+
if (score.isBust()) return BUST
|
|
239
|
+
return STAY
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
→ **`STAY = else fallback`** = *블랙잭/Bust 아니면 STAY*. *진행 중 (Hit 가능) + Stay (자발 정지) 구분 부재*. *PR #152·#136·#93·#85 의 Hit/Stay 별도 상태* 와 *반대 트레이드오프*. *STAY = 결과 상태 (분기 후 비교)*. *Hit 도 STAY 로 흡수* — *상태 표현 부족*. *enum 3개로 단순화 + 분기 응집* vs *상태 객체 다형성* 의 트레이드오프.
|
|
246
|
+
|
|
247
|
+
### 13. `ProfitCalculator` 의 *2 단계 분기 (`?:`) 흐름* — *Tell-Don't-Ask 미달*
|
|
248
|
+
|
|
249
|
+
```kotlin
|
|
250
|
+
fun calculateProfit(dealer: Dealer, player: Player): Money =
|
|
251
|
+
getMoneyByGameStatusOrNull(dealer, player) ?: getMoneyByCompareToScore(dealer, player)
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
→ **`getMoneyByGameStatusOrNull` 가 *BLACKJACK / BUST 분기 + null fallback*** + **`getMoneyByCompareToScore` 가 *점수 비교***. *2 단계 정적 헬퍼*. *Player.profit(dealer): Money* 같은 *Player 메시지*가 *책임 응집*. PR #131·#136·#132·#137 와 같은 결.
|
|
255
|
+
|
|
256
|
+
또한 *`getMoneyByGameStatusOrNull` 반환 Money?* — *nullable* 가 *fallback 신호*. *Money.NONE / Money.zero()* 같은 *명시적 null object* 패턴이 *호출자 안전성*. 다만 *현재 ?:* 흐름은 *Kotlin 어휘로 간결*.
|
|
257
|
+
|
|
258
|
+
### 14. `Dealer` 가 *기본 생성자 noargs + companion DEALER_NAME default* — 정공
|
|
259
|
+
|
|
260
|
+
```kotlin
|
|
261
|
+
class Dealer(name: String = DEALER_NAME) : Participant(name) { ... }
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
→ **default 값 = 도메인 표준 ("딜러")**. PR #131·#137·#136·#108·#133 와 같은 결의 *Dealer 기본 이름*. *외부 변경 불가능 (val)* + default 일관.
|
|
265
|
+
|
|
266
|
+
### 15. `BlackjackGame.gameReady` / `gameStart` / `gameResult` — *3 단계 함수 분리 + Controller 책임 흡수*
|
|
267
|
+
|
|
268
|
+
```kotlin
|
|
269
|
+
fun start() {
|
|
270
|
+
val (dealer, players, gameManager) = gameReady()
|
|
271
|
+
gameStart(dealer, players, gameManager)
|
|
272
|
+
gameResult(dealer, players, gameManager)
|
|
273
|
+
}
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
학생 자가 답변 (Controller 토론): *"해당 구조는 여러 컨트롤러에서 사용해야하는 경우 추상화된 View 구현체만 존재한다면 쉽게 적용할 수 있다는 장점이 있을 것 같습니다. 하지만 현재 프로그램에서는 단순하게 컨트롤러를 2번 타고 들어가는 느낌이라 효율적이진 못한 것 같습니다."*
|
|
277
|
+
|
|
278
|
+
두루 답변: *"현재 구현을 보면 `BlackjackGame`은 컨트롤러의 느낌이 강하기는 하다는 생각이 듭니다. `View의 값을 받아서 객체를 생성하고 블랙잭 게임이 돌아가도록 진행의 흐름을 관리`하여 Controller의 느낌이 강합니다!"*
|
|
279
|
+
|
|
280
|
+
→ **BlackjackGame = Controller 변형**. PR #131·#132·#136·#152 와 같은 결의 *Engine god-object*. *학생 자가 회의 + reviewer 동의 = 트레이드오프 인식*.
|
|
281
|
+
|
|
282
|
+
### 16. `GameManager.processDrawOrStayBasedOnPlayer` 복잡한 메서드명
|
|
283
|
+
|
|
284
|
+
```kotlin
|
|
285
|
+
fun processDrawOrStayBasedOnPlayer(
|
|
286
|
+
player: Player,
|
|
287
|
+
playerDrawDecision: (Player) -> CardDrawDecision,
|
|
288
|
+
showPlayerHands: (Player) -> Unit,
|
|
289
|
+
) { ... }
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
→ **`processDrawOrStayBasedOnPlayer` = *길고 의미 모호***. *Kotlin 어휘 = `playPlayerTurn(player, ...)` 또는 `runPlayerRound(player, ...)`* 가 *간결*. *process + BasedOn* 접두사 어색. PR #137 (지훈 권고: `onXX`) 와 같은 결의 *콜백 어휘*.
|
|
293
|
+
|
|
294
|
+
### 17. `Score.isBlackjackNumber() = number == 21` — *블랙잭 ≠ 21 점*
|
|
295
|
+
|
|
296
|
+
```kotlin
|
|
297
|
+
fun isBlackjackNumber(): Boolean = number == BUST_NUMBER // 21
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
→ **`isBlackjackNumber` = *21 점***. *블랙잭 룰 = 2장 + 21*. *3장 21 도 isBlackjackNumber == true*. *naming misleading*. *isMaxScore() = 21 점* / *블랙잭 판정은 GameStatus.of 에서 cardCount 함께 검사* — 룰은 정합. 다만 *Score 메서드 이름*에 *블랙잭* 들어가면 *호출자 오해 가능성*.
|
|
301
|
+
|
|
302
|
+
### 18. `ScoreCalculator → Score 변경 트레이드오프* — 학생 자가 학습*
|
|
303
|
+
|
|
304
|
+
두루 진단 (Score.kt:9): *"사실 이전에 ScoreCalculator를 만들어 보도록 하게 코멘트를 남겨두었던 이유는, 현재처럼 Score객체가 만들어 지다보면, 객체간의 뎁스가 깊어지는 형태가 될 수 있어서 Utils 형식으로 점수 계산기를 만들어보도록 했었어요!"*
|
|
305
|
+
|
|
306
|
+
→ **Helper (ScoreCalculator) vs 도메인 객체 (Score) 트레이드오프**. *Helper = 깊이 ↓ + 도메인 누수*. *도메인 객체 = 깊이 ↑ + 책임 응집*. *학생 자가 결정 = 도메인 객체*. PR #131·#136·#137·#90 와 같은 결의 *Score 객체 분리*.
|
|
307
|
+
|
|
308
|
+
### 19. `GameManager.fold` 함수형 어휘 활용
|
|
309
|
+
|
|
310
|
+
```kotlin
|
|
311
|
+
fun getDealerProfit(playersProfitInfo: List<ParticipantProfitInfo>): ParticipantProfitInfo {
|
|
312
|
+
val playersSum = playersProfitInfo.fold(Money.from(0L)) { sum, player -> sum + player.profit }
|
|
313
|
+
return ParticipantProfitInfo(dealer.name, Money.toDealerMoney(playersSum))
|
|
314
|
+
}
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
→ **`fold` 사용 = Kotlin 함수형 어휘**. *PR #49 의 var profit + forEach* 와 *반대 트레이드오프* — *함수형 정공*. *operator plus*도 활용. PR #131·#132·#133·#137 와 같은 결.
|
|
318
|
+
|
|
319
|
+
### 20. `BlackjackGame.gameStart` 의 *Dealer 블랙잭 조기 종료* — 정확
|
|
320
|
+
|
|
321
|
+
```kotlin
|
|
322
|
+
private fun gameStart(...) {
|
|
323
|
+
if (!dealer.isBlackjack()) {
|
|
324
|
+
playersDrawCards(...)
|
|
325
|
+
dealerDrawCards(...)
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
→ **딜러 블랙잭 시 모든 진행 skip**. *카지노 룰 = 딜러 블랙잭 시 플레이어 블랙잭 만 무승부, 나머지 패배*. PR #137·#136 와 같은 결의 *블랙잭 룰 정확성*.
|
|
331
|
+
|
|
332
|
+
## 리뷰어 의견 요지
|
|
333
|
+
|
|
334
|
+
- **typealias = Pair/Triple 익명 의미 부여 시 유용, 3+ 멤버 시 클래스** — 트레이드오프 양면 명시.
|
|
335
|
+
- **`distribute → draw` naming = 책임 표현** — *카드 뽑는 메시지*.
|
|
336
|
+
- **Demeter vs 의도 표현 트레이드오프** — *깊이 < 의도*. *Money.toBlackjackMoney vs money.toBlackjackMoney() 양쪽 합리*.
|
|
337
|
+
- **YAGNI 원칙** — *확장성 고려 < 필요할 때 구현*.
|
|
338
|
+
- **`ScoreCalculator` (Helper) vs `Score` (도메인 객체)** — *깊이 + 책임 응집 트레이드오프*.
|
|
339
|
+
- **value class + @JvmInline = 원시 박싱 없음 + 도메인 어휘** — *학생 자가 학습 모범*.
|
|
340
|
+
- **`data class` vs `class` + `toString` 활용** — *학생 자가 학습 + 의견 풍부*.
|
|
341
|
+
- **`toUi()` Extension 분리 = 다른 View 재사용 가능** — *Kotlin Extension function 활용*.
|
|
342
|
+
- **3 변수 제약 = 연습 도구** — *Wrapper 시도 후 잘못된 설계 인식 자가 후퇴*.
|
|
343
|
+
- **BlackjackGame = Controller 느낌 강함** — *학생 자가 회의 + reviewer 동의*.
|
|
344
|
+
|
|
345
|
+
## 대표 인용
|
|
346
|
+
|
|
347
|
+
**두루 (typealias 트레이드오프 인정, BlackjackGame.kt:10):**
|
|
348
|
+
> `typealias`에 대한 의견 정말 좋습니다👍
|
|
349
|
+
> 저는 사실 `typealias`를 잘 사용하지는 않긴 합니다😅
|
|
350
|
+
> 이유는 채넛이 말씀해주신대로, `어떤 데이터를 담고 있는 지 명시해놓은 부분을 확인`을 해야하기 때문이에요
|
|
351
|
+
> 구현하는 내용이 많아지다 보면 네이밍에 명확하게 드러나지 않는다면, 직접 구현을 한 저도 몇달 몇년 뒤에 내용을 살펴볼 때 결국엔 `어떤 것 데이터인지 결국에는 찾아봐야만`해서요..
|
|
352
|
+
>
|
|
353
|
+
> 만약 사용한다고 하면, `typealias Participants = Pair<Dealer, List<Player>>`까지는 그래도 어떤 것을 반환하는지 조금은 알 수 있어서 활용을 해볼 수 있을 것 같은데, `typealias GameFactor = Triple<Dealer, List<Player>, GameManager>`형태는 지양을 해볼 것 같긴 합니다만, 현재처럼 구현이 길지 않을 때는 사용하는 것도 좋아 보이네요ㅎㅎ💯
|
|
354
|
+
|
|
355
|
+
**두루 (Demeter vs 의도, ProfitCalculator.kt:24):**
|
|
356
|
+
> 어떻게 로직이 구성되어 있는지 모르고 딱 해당 부분의 코드만 봤을 때, 아래와 같은 생각이 처음에 들기는 했었어요
|
|
357
|
+
> - `Money.toBlackjackMoney(player.money)` : Money 는 Helper 객체인가?, Player의 money를 받아서 blackjack 인 경우 이윤을 알려주나 보구나
|
|
358
|
+
> - `player.money.toBlackjackMoney()` : 뎁스가 깊기는 한데, 블랙잭에 이윤을 알려주는 거긴 하구나
|
|
359
|
+
> ...
|
|
360
|
+
> 참고로 뎁스 형식이 무조건적으로 나쁜것만은 아니긴 합니다
|
|
361
|
+
> 그치만 뎁스 형식으로 한다면, 수정들에 대해서 유의해야 하는 단점도 있습니다
|
|
362
|
+
|
|
363
|
+
**두루 (Helper vs 도메인 객체 트레이드오프, Score.kt:9):**
|
|
364
|
+
> 아하~ Score객체가 추가되었군요!👍
|
|
365
|
+
> ...
|
|
366
|
+
> 사실 이전에 ScoreCalculator를 만들어 보도록 하게 코멘트를 남겨두었던 이유는, 현재처럼 Score객체가 만들어 지다보면, 객체간의 뎁스가 깊어지는 형태가 될 수 있어서 Utils 형식으로 점수 계산기를 만들어보도록 했었어요!
|
|
367
|
+
|
|
368
|
+
**두루 (BlackjackGame = Controller 느낌, BlackjackController.kt:10):**
|
|
369
|
+
> 현재 구현을 보면 `BlackjackGame`은 컨트롤러의 느낌이 강하기는 하다는 생각이 듭니다
|
|
370
|
+
> `View의 값을 받아서 객체를 생성하고 블랙잭 게임이 돌아가도록 진행의 흐름을 관리`하여 Controller의 느낌이 강합니다!
|
|
371
|
+
|
|
372
|
+
**학생 자가 학습 (typealias 장단점, BlackjackGame.kt:10):**
|
|
373
|
+
> `typealias` 사용하게 된 이유는 반환값으로 여러 데이터를 한 번에 넘겨야 하는 상황이 있었는데 그 외 다른 곳에서는 사용할 일이 없어서 클래스를 만드는 것보다는 `typealias`를 선택하는 것이 효율적으로 생각되었습니다.
|
|
374
|
+
>
|
|
375
|
+
> 장점으로는 클래스를 생성하지 않아도 이름으로 의미를 전달할 수 있다고 생각되었고 현재 사용코드에서의 Triple, Pair 같은 경우 data class로 구현되어 있기에 data class 에서 제공하는 기능인 componentN()도 활용할 수 있듯이 타입 또는 자료구조의 기능을 동일하게 사용할 수 있다는 점이 장점이라고 생각합니다.
|
|
376
|
+
> 단점으로는 typealias가 어떤 데이터를 담고 있는 지 명시해놓은 부분을 확인해야만 알 수 있다는 점과 클래스인지 typealias 인지 이름만 봤을 때 판단하기 어려워 혼란을 줄 수 있을 것 같습니다.
|
|
377
|
+
|
|
378
|
+
**학생 자가 학습 (YAGNI 원칙 인용, ScoreCalculator.kt):**
|
|
379
|
+
> 확장성을 고려해 만들다보니 생긴 코드였습니다.
|
|
380
|
+
>
|
|
381
|
+
> > YAGNI 프로그래머가 필요하다고 간주할 때까지 기능을 추가하지 않는 것이 좋다는 XP의 원칙이다.
|
|
382
|
+
> "실제로 필요할 때 무조건 구현하되, 그저 필요할 것이라고 예상할 때에는 절대 구현하지 말라."
|
|
383
|
+
>
|
|
384
|
+
> 앞으로는 위의 규칙에 따라 필요한 기능만을 구현하고 필요하게 되면 리팩터링을 진행해보겠습니다.
|
|
385
|
+
|
|
386
|
+
**학생 자가 학습 (Demeter vs 의도 표현, ProfitCalculator.kt:24):**
|
|
387
|
+
> `Money.toBlackjackMoney(player.money) : Money 는 Helper 객체인가?, Player의 money를 받아서 blackjack 인 경우 이윤을 알려주나 보구나`
|
|
388
|
+
> `player.money.toBlackjackMoney() : 뎁스가 깊기는 한데, 블랙잭에 이윤을 알려주는 거긴 하구나`
|
|
389
|
+
>
|
|
390
|
+
> 라는 설명을 보니 `depth`가 깊은 것에 대한 생각을 다시 해보게 되었고 `depth` 깊이보다는 의도를 명확히 표현할 수 있는지가 더 중요하다고 느꼈습니다.
|
|
391
|
+
>
|
|
392
|
+
> 이번 미션에서는 헬퍼 역할보다는 도메인 역할을 기대하고 만들었기에 `Money` 객체에게 메시지를 전송하는 방식을 선택해보려고 합니다!
|
|
393
|
+
|
|
394
|
+
**학생 자가 학습 (data class + toString trade-off, ParticipantProfitInfo.kt:8):**
|
|
395
|
+
> `data class`는 `toString()`, `equals()`, `hashCode()`, `componentN()`, `copy()` 메서드를 제공해주는 이점이 있습니다.
|
|
396
|
+
> 해당 메서드들이 필요한 경우에 `data class`를 선택할 것 같습니다.
|
|
397
|
+
> 그 중 `copy()` 메서드의 경우 List 와 같은 자료구조의 제네릭 타입이 Card, Member, Person 등 참조형일 경우 원소들이 얕은 복사가 진행되는 것으로 알고 있어 사용에 유의해야 할 것 같습니다.
|
|
398
|
+
>
|
|
399
|
+
> `View`에서 활용할 때 클래스 내에 오버라이딩 된 `toString()`을 사용한다면 `View`를 변경하고 싶을 때에도 도메인 코드까지 확인해야 한다는 문제와 여러 군데에서 출력을 위해 호출하지만 출력 형태가 다를 경우 `toString()`이 어떤 출력 형태를 반환하는 지 알기 어려워 혼란을 줄 수 있을 것 같습니다.
|
|
400
|
+
> 그렇기에 제시해준 방법처럼 Extension 클래스를 생성해서 출력형식을 관리하거나 View 클래스내에서 출력을 위한 형태로 변환해줄 것 같습니다.
|
|
401
|
+
|
|
402
|
+
**학생 자가 학습 (3 변수 제약 자가 회의, Money.kt):**
|
|
403
|
+
> 사실 Player와 Money를 상태를 갖고 있는 `PlayerTable` 의 이름의 객체를 생성했었습니다.
|
|
404
|
+
> 현재 구조에서 Player 역할이 모두 `PlayerTable`을 통해서 수행되어야 했기에 많은 부분이 변경되다보니 잘못된 설계로 인해 변경부분이 많다고 생각되어 임시로 `Player` 프로퍼티로 갖게 되었습니다.
|
|
405
|
+
|
|
406
|
+
## 얻은 교훈
|
|
407
|
+
|
|
408
|
+
1. ***`typealias` = Pair/Triple 익명 의미 부여 시 유용, 3+ 멤버 시 data class***. *2 멤버 (Pair<Dealer, List<Player>>) = typealias 합리*. *3 멤버 (Triple<Dealer, List<Player>, GameManager>) = data class 가 명시*. 트레이드오프 양면 인식 + reviewer 자가 사용 의견. **MCP 룰 후보 — `typealias-vs-class`** (3+ 멤버 시 클래스 권고).
|
|
409
|
+
|
|
410
|
+
2. ***Demeter vs 의도 표현 트레이드오프 = 깊이 < 의도***. *`Money.toBlackjackMoney(player.money)` (Helper 느낌) vs `player.money.toBlackjackMoney()` (도메인 메시지)* 의 *둘 다 합리*. *깊이 깊은 것이 무조건 나쁜 것 X*. *의도 명료성 우선*. PR #133·#88·#137·#108 와 같은 결.
|
|
411
|
+
|
|
412
|
+
3. ***YAGNI = 필요할 때 무조건 구현, 예상할 때 절대 구현 X***. *학생 자가 인용 + 후속 반영*. *확장성 고려가 만든 dead code*. *현재 사용처에서 시작 + 필요 시 추가* 정공. PR #136·#137·#88·#103 와 같은 결.
|
|
413
|
+
|
|
414
|
+
4. ***ScoreCalculator (Helper) vs Score (도메인 객체) 트레이드오프***. *Helper = 깊이 ↓ + 책임 분산*. *도메인 객체 = 깊이 ↑ + 책임 응집*. *학생 자가 결정 = 도메인 객체 + 의도 명시* 모범. PR #131·#136·#137·#90 와 같은 결.
|
|
415
|
+
|
|
416
|
+
5. ***`@JvmInline value class + Comparable + operator overloading + private constructor + factory` Kotlin 어휘 종합 활용***. *Score / Money 둘 다 활용*. PR #90·#131·#132·#136·#137 와 같은 결.
|
|
417
|
+
|
|
418
|
+
6. ***`Score.isDrawableCardByDealer() = number < 17` Score 가 Dealer 룰 알기 = 룰 누수***. *Dealer.canDraw() = score < 17 안*에서 직접*이 정공*. PR #131·#136·#108·#137·#90 와 같은 결.
|
|
419
|
+
|
|
420
|
+
7. ***Ace 보너스 +10 패턴 누락 가능성***. *`optimizedSum` 이 *Ace 1 기본 + Bust 시 -10 반복** — *Bust 아닌 Ace 11 시도 부재*. *현재 코드 룰 부정확*. *Ace 11 우선 + Bust 시 1 변환* 또는 *base + Ace 보너스 +10 if ≤21* 표준 패턴. PR #128·#114·#125·#108·#131·#136·#137·#41 와 같은 결.
|
|
421
|
+
|
|
422
|
+
8. ***`distribute → draw` naming = 책임 표현 (카드 뽑는 메시지)***. *분배자 입장 vs 행위 입장*. *draw 가 *카드 뽑기 메시지* 어휘 정공*. PR #133·#88·#137·#136 와 같은 결.
|
|
423
|
+
|
|
424
|
+
9. ***`toString` View 활용 트레이드오프***. *도메인 객체 내 toString = View 변경 시 도메인 수정*. *Extension function (`.toUi()`) 분리 = 다른 View 재사용*. *학생 자가 학습 + Extension 분리 정공*. PR #88·#137·#90 와 같은 결.
|
|
425
|
+
|
|
426
|
+
10. ***3 변수 제약 = 연습 도구, Wrapper 시도 + 잘못된 설계 자가 후퇴***. *학생 PlayerTable Wrapper → 변경 파급 ↑ → 임시 Player 프로퍼티 보유 결정*. *Reviewer 두루 동의*. PR #133·#88·#132·#136·#41·#49 와 같은 결.
|
|
427
|
+
|
|
428
|
+
11. ***BlackjackGame = Controller 느낌 자가 회의 + reviewer 동의***. *학생 + reviewer 양방향 트레이드오프 인식*. *Game 도메인 객체 vs Controller 변형 경계 모호*. PR #131·#132·#136·#152·#58 와 같은 결.
|
|
429
|
+
|
|
430
|
+
12. ***`open class Participant` vs abstract class 트레이드오프***. *open = 인스턴스화 가능 + 자식 override 가능*. *abstract = 인스턴스화 불가 + abstract method 강제*. *PR #49·#131·#132·#136 의 abstract 다형성* 와 *반대 트레이드오프*. *PR #146 = open + 공통 행동 + Player/Dealer 자기 메서드*.
|
|
431
|
+
|
|
432
|
+
13. ***`Hand` 외부 노출 (`val hand`) = Demeter 위반 표면***. *Participant.cards() / Participant.score()* 위임 메서드가 정공. *두루 권고 = Participant 가 Hand 상속* 도 대안. PR #88·#133·#108·#137 와 같은 결.
|
|
433
|
+
|
|
434
|
+
14. ***`ProfitCalculator object` 정적 헬퍼 + nullable fallback (`?:`)*** — *Tell-Don't-Ask 미달*. *Player.profit(dealer): Money* 같은 *Player 메시지*가 정공. *학생 자가 인식 (ScoreCalculator → Score 변환) + ProfitCalculator 도 같은 결*. PR #131·#136·#132·#137·#49 와 같은 결.
|
|
435
|
+
|
|
436
|
+
15. ***`fold` 함수형 어휘 = Kotlin 정공***. *var + forEach* 대신 *fold/sumOf*. *Money + Money operator plus* 활용. PR #131·#132·#133·#137·#49 와 같은 결.
|
|
437
|
+
|
|
438
|
+
16. ***`processDrawOrStayBasedOnPlayer` 길고 모호한 메서드명 vs `onXX` 콜백 어휘***. *PR #137 의 onEndDealerTurn* 와 *반대 트레이드오프*. *`playPlayerTurn(player, ...)` 같은 *명사+동사 한 단어* 가 *Kotlin 어휘 정공*.
|
|
439
|
+
|
|
440
|
+
17. ***학생 자가 학습 + reviewer 자가 의견 + 트레이드오프 양면 인식 = 학습 가시화 최고 수준***. *typealias / Demeter vs 의도 / Helper vs 도메인 / data class vs class / 3 변수 제약* 모두 *양면 트레이드오프 인식 + 결정 근거 명시*. PR #128·#135·#108·#133·#136·#137·#41·#88 와 같은 결.
|
|
441
|
+
|
|
442
|
+
18. ***`STAY = else fallback` enum 단순화 vs State 객체 다형성 트레이드오프***. *PR #146 = enum 3개 단순* / *PR #152·#136·#93·#85 = State 객체 다형성*. *enum + GameStatus.of factory* 가 *간결 + 분기 응집*. *State 객체*는 *상태별 행동 차이 표현*. *둘 다 합리*.
|
|
443
|
+
|
|
444
|
+
19. ***딜러 카드 한 번만 뽑기 = 룰 부정확 가능성***. *`isDrawCardBasedOnDealer()` 한 번 호출 = 1장 받음*. *Dealer 룰 = 17 이상까지 hit* — *호출자가 반복 호출 강제*. *Dealer.drawUntilStand(deck)* 내부 응집 정공. PR #152 (모찌) 의 *dealerTurn while + return 논리 오류* 와 같은 결의 *Dealer 자기 룰 응집 부재*.
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
# PR #27 — [멧돼지] 1단계 로또
|
|
2
|
+
|
|
3
|
+
- **Reviewee:** [@2chang5](https://github.com/2chang5)
|
|
4
|
+
- **PR:** https://github.com/woowacourse/kotlin-lotto/pull/27
|
|
5
|
+
- **단계:** 1단계
|
|
6
|
+
- **리뷰어:** @laco-dev
|
|
7
|
+
- **라인 코멘트:** 70
|
|
8
|
+
|
|
9
|
+
## 잘한 점 (설계 관점)
|
|
10
|
+
|
|
11
|
+
- **`PurchaseMoney`, `LottoBunch`, `WinningLotto`, `WinningResult` 도메인 분리**.
|
|
12
|
+
- **`Bank` 객체 시도** (이름은 모호).
|
|
13
|
+
- **`Validator` 분리**.
|
|
14
|
+
|
|
15
|
+
## 못한 점 (설계 관점)
|
|
16
|
+
|
|
17
|
+
### 1. Controller가 ","로 split하기 + Int 검증
|
|
18
|
+
|
|
19
|
+
```kotlin
|
|
20
|
+
class LottoController {
|
|
21
|
+
fun run() {
|
|
22
|
+
val moneyInput = InputView.readMoney() // Int 반환
|
|
23
|
+
val purchaseMoney = PurchaseMoney(moneyInput)
|
|
24
|
+
.
|
|
25
|
+
val winningInput = InputView.readWinningNumbers()
|
|
26
|
+
val numbers = winningInput.split(",").map { it.trim().toInt() } // ⚠ Controller가 파싱
|
|
27
|
+
.
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
리뷰어 핵심:
|
|
33
|
+
|
|
34
|
+
> 위 코드에서 InputView로부터 받아야 하는 값은 Int 값이 됩니다. 그런데 이 Int는 무엇으로 부터 만들어졌는지, 컨트롤러가 알 필요가 있을까요? 콘솔로부터 받을 수도 있고, 유저가 화면을 터치해서 받을 지도 모릅니다. 근본적으로 만들고 싶은 것은 PurchaseMoney이고 무엇으로 부터 필요한 Int를 만들지는 InputView의 구현의 책임으로 간다고 생각합니다.
|
|
35
|
+
|
|
36
|
+
→ Controller는 `PurchaseMoney`라는 도메인을 받기를 원할 뿐, *콘솔/터치/CSV* 같은 입력 형식은 무지해야.
|
|
37
|
+
|
|
38
|
+
→ "domain 레이어는 view를 알면 안되지만, view에서는 domain을 알기 때문에 저는 InputView에서 바로 domain 모델을 만드는 방법을 선호하는 편입니다."
|
|
39
|
+
|
|
40
|
+
### 2. Controller 안에 일반화된 입력 헬퍼 — `Any` 반환
|
|
41
|
+
|
|
42
|
+
```kotlin
|
|
43
|
+
private fun <T> getValidInput(input: () -> T, validator: (T) -> Unit): Any {
|
|
44
|
+
while (true) {
|
|
45
|
+
try {
|
|
46
|
+
val result = input()
|
|
47
|
+
validator(result)
|
|
48
|
+
return result
|
|
49
|
+
} catch (e: IllegalArgumentException) {. }
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
리뷰어:
|
|
55
|
+
|
|
56
|
+
> 위 함수들의 목적과 역할이 단순히 코드 반복을 줄이려고 만들어 졌지만, 여러가지 높은 위험성을 가지고 있습니다.
|
|
57
|
+
> 1. Any 타입을 반환하기 때문에 강제로 캐스팅 하는 등 타입 안전성에 대한 위험성
|
|
58
|
+
> 2. 특정 오류를 일반화 시킴으로써 예외 처리가 의도치 않게 동작할 수 있다는 위험성
|
|
59
|
+
|
|
60
|
+
→ 일반화의 비용 = 타입 안전성. 미션 규모에서는 *중복을 허용*.
|
|
61
|
+
|
|
62
|
+
### 3. 상수 파일 `LottoRule.kt`가 도메인 정보 보유
|
|
63
|
+
|
|
64
|
+
```kotlin
|
|
65
|
+
object LottoRule {
|
|
66
|
+
const val MIN_NUMBER = 1
|
|
67
|
+
const val MAX_NUMBER = 45
|
|
68
|
+
const val LOTTO_SIZE = 6
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
리뷰어:
|
|
73
|
+
|
|
74
|
+
> 로또의 최솟값과 최댓값은 로또 번호가 가지는 명확한 개념이 아닐까요? 이 값을 공통으로 사용하게 되면, 로또 번호에게 협력을 하지 않고 모두 가져다 쓰는 문제가 될 수 있습니다. 로또 번호에게 필요한 내용을 요청해서 받아오도록 만들어 보세요.
|
|
75
|
+
|
|
76
|
+
→ MIN/MAX 같은 도메인 invariant는 `LottoNumber` 객체의 영역. 상수로 노출하면 외부에서 가져다 쓰며 도메인이 *수동적*이 됨.
|
|
77
|
+
|
|
78
|
+
### 4. `Bank` — 이름과 책임 불명확
|
|
79
|
+
|
|
80
|
+
```kotlin
|
|
81
|
+
class Bank(.) {
|
|
82
|
+
fun calculate(.): Double =. // 수익률만 계산
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
리뷰어:
|
|
87
|
+
|
|
88
|
+
> Bank는 무슨 의미를 가진다고 생각하셨나요? 이 객체의 역할과 이름이 잘 드러나도록 작성이 되었을까요?
|
|
89
|
+
|
|
90
|
+
→ "Bank"가 *금융 기관*인지, *결과 계산기*인지, *상금 보유자*인지 모호.
|
|
91
|
+
|
|
92
|
+
### 5. `Bank` 내부에서 외부 객체 정보 직접 꺼내기 (feature-envy)
|
|
93
|
+
|
|
94
|
+
```kotlin
|
|
95
|
+
class Bank {
|
|
96
|
+
fun calculate(lottoBunch: LottoBunch, winningResult: WinningResult): Double {
|
|
97
|
+
val purchaseMoney = lottoBunch.size * LOTTO_PRICE // ⚠ 다른 객체 정보 꺼내기
|
|
98
|
+
val prize = winningResult.totalPrize()
|
|
99
|
+
return prize.toDouble() / purchaseMoney
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
> 각 객체에 있는 값을 직접 꺼내와서 로직을 처리하지 않고, 객체에 요청을 보내서 원하는 값을 처리하도록 해보세요. 객체지향 에서는 이 개념을 메시지를 보낸다 라고 표현합니다.
|
|
105
|
+
|
|
106
|
+
### 6. Grade → Rank 리네임 후 함수명 그대로
|
|
107
|
+
|
|
108
|
+
```kotlin
|
|
109
|
+
enum class Rank(.) {
|
|
110
|
+
.
|
|
111
|
+
fun calculateGradePrize(.): Int =. // ⚠ Grade 시절 이름
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
> 구현하면서 Grade에서 Rank로 변경된 것 같은데 함수 이름은 남아있는 것 처럼 보이네요
|
|
116
|
+
|
|
117
|
+
### 7. `Rank.prizeMoney`가 property + 동명 함수 둘 다
|
|
118
|
+
|
|
119
|
+
```kotlin
|
|
120
|
+
enum class Rank(val prizeMoney: Int) {
|
|
121
|
+
.
|
|
122
|
+
fun getPrizeMoney(): Int = prizeMoney // ⚠ 중복
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
> Rank가 prizeMoney를 프로퍼티로 가지고 있는데, 이 함수의 목적은 무엇일까요?
|
|
127
|
+
|
|
128
|
+
## 리뷰어 의견 요지
|
|
129
|
+
|
|
130
|
+
리뷰어 @laco-dev의 핵심 메시지:
|
|
131
|
+
|
|
132
|
+
1. **InputView가 *도메인 객체*를 반환** — Controller가 파싱/검증/조립을 모르게. "view → domain 의존은 허용".
|
|
133
|
+
|
|
134
|
+
2. **도메인 invariant는 도메인 객체에**. `LottoRule` 같은 상수 파일은 god-folder 패턴. `LottoNumber.MIN`/`MAX`로.
|
|
135
|
+
|
|
136
|
+
3. **`Any` 반환의 위험** — 타입 안전성 잃음. 일반화 비용 > 중복 비용일 때만 일반화.
|
|
137
|
+
|
|
138
|
+
4. **이름과 책임의 동기화** — 리네임 시 함수명까지. 모호한 이름 (`Bank`)은 책임이 드러나는 이름으로.
|
|
139
|
+
|
|
140
|
+
- **대표 인용:**
|
|
141
|
+
> 도메인 레이어는 view를 알면 안되지만, view에서는 domain을 알기 때문에 저는 InputView에서 바로 domain 모델을 만드는 방법을 선호하는 편입니다.
|
|
142
|
+
>
|
|
143
|
+
> — @laco-dev on `src/main/kotlin/lotto/LottoController.kt`
|
|
144
|
+
|
|
145
|
+
> 로또의 최솟값과 최댓값은 로또 번호가 가지는 명확한 개념이 아닐까요? 이 값을 공통으로 사용하게 되면, 로또 번호에게 협력을 하지 않고 모두 가져다 쓰는 문제가 될 수 있습니다.
|
|
146
|
+
>
|
|
147
|
+
> — @laco-dev on `src/main/kotlin/lotto/constant/LottoRule.kt`
|
|
148
|
+
|
|
149
|
+
## 얻은 교훈
|
|
150
|
+
|
|
151
|
+
- **InputView가 도메인 객체 반환 가능**. view → domain 의존은 허용되므로 InputView 안에서 도메인을 *조립*해 Controller에 *완성품*을 넘김.
|
|
152
|
+
- **`LottoRule` 같은 상수 파일 = 도메인 비활성화**. 모든 곳이 상수를 가져다 쓰면 도메인 객체는 *수동적*. 도메인이 *자기 규칙을 소유*해야 협력이 생김.
|
|
153
|
+
- **`Any` 반환 = 일반화의 함정**. 타입 안전성 잃으면 호출자가 캐스팅 부담. 미션 규모에서는 *중복 허용*이 더 안전.
|
|
154
|
+
- **리네임은 *연관 이름까지*** — Grade → Rank 변경 시 `calculateGradePrize` → `calculatePrize`까지.
|
|
155
|
+
- **`property + 동명 getter` 중복** = Kotlin에서 거의 항상 잘못된 패턴. property 하나면 됨.
|