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,124 @@
|
|
|
1
|
+
# PR #108 — [로또 1단계] 채넛 미션
|
|
2
|
+
|
|
3
|
+
- **Reviewee:** [@yrsel](https://github.com/yrsel)
|
|
4
|
+
- **PR:** https://github.com/woowacourse/kotlin-lotto/pull/108
|
|
5
|
+
- **단계:** 1단계
|
|
6
|
+
- **리뷰어:** @laco-dev
|
|
7
|
+
- **라인 코멘트:** 62
|
|
8
|
+
|
|
9
|
+
## 잘한 점 (설계 관점)
|
|
10
|
+
|
|
11
|
+
- **`LottoMachine` 도메인 추출** — 로또 생성 책임.
|
|
12
|
+
- **PR 본문 자가 의문 명시** — MVC 구조, 랜덤 테스트, 입력 검증.
|
|
13
|
+
- **페어 진행**.
|
|
14
|
+
|
|
15
|
+
## 못한 점 (설계 관점)
|
|
16
|
+
|
|
17
|
+
### 1. Controller의 검증 + 출력 책임 분산
|
|
18
|
+
|
|
19
|
+
```kotlin
|
|
20
|
+
class LottoController {
|
|
21
|
+
fun run() {
|
|
22
|
+
val amount = readAmount()
|
|
23
|
+
// 검증
|
|
24
|
+
// 출력
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
학생 PR 본문:
|
|
30
|
+
|
|
31
|
+
> MVC 패턴에 대한 controller 구조가 잘 이루어져있는지 궁금합니다.
|
|
32
|
+
|
|
33
|
+
리뷰어 답:
|
|
34
|
+
|
|
35
|
+
> Controller에서 검사를 통해 다시 재입력받는 것도 좋은 전략입니다. 한가지 생각해 볼만한 점은 입력을 받는 것과 InputView에서 발생한 오류를 OutputView로 넘겨서 출력하는게 적절한가? 에 대해서인데요. 우리가 입력을 키오스크에서 받는다고 가정해보면 키오스크에 UI가 출력되니까요!?
|
|
36
|
+
|
|
37
|
+
→ InputView와 OutputView가 둘 다 *같은 UI 매체*면 합칠 수 있다. CLI에서 print + readLine은 같은 콘솔.
|
|
38
|
+
|
|
39
|
+
### 2. `LottoMachine`이 Random 직접 의존
|
|
40
|
+
|
|
41
|
+
```kotlin
|
|
42
|
+
class LottoMachine {
|
|
43
|
+
fun generate(): Lotto {
|
|
44
|
+
val numbers = (1..45).shuffled().take(6).sorted()
|
|
45
|
+
return Lotto(numbers)
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
학생 의문:
|
|
51
|
+
|
|
52
|
+
> 로또 번호 생성하는 로직을 LottoMachine 객체에서 진행하는데 랜덤값에 대한 테스트를 어떤 방식으로 진행하면 좋을 지 궁금합니다.
|
|
53
|
+
|
|
54
|
+
리뷰어 답:
|
|
55
|
+
|
|
56
|
+
> 객체지향 관점으로 접근해본다면, 우리가 하고 싶은 것은 로또 번호를 생성하는 것이지 랜덤하게 뽑는 것이 아닙니다. 추상화 한 단계에서는 *어떻게* 뽑는지가 아닌 *무엇을 만드는지*에 집중.
|
|
57
|
+
|
|
58
|
+
→ `NumberGenerator` 인터페이스 + Random 구현체 + Fixed 테스트 더블.
|
|
59
|
+
|
|
60
|
+
### 3. 함수가 2가지 일
|
|
61
|
+
|
|
62
|
+
```kotlin
|
|
63
|
+
fun getLottos(): List<Lotto> {
|
|
64
|
+
val lottos = lottoMachine.generate(count)
|
|
65
|
+
OutputView.printLottos(lottos) // ⚠ 가져오기 + 출력
|
|
66
|
+
return lottos
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
> 로또 번호를 가져오는데 OutputView에 출력까지 한다는 것을 예측하기 어렵지 않을까요? 함수가 2가지의 역할을 하고 있는건 아닌지 생각해봐야 합니다.
|
|
71
|
+
|
|
72
|
+
→ `getLottos()`는 가져오기만, 호출자가 출력 호출.
|
|
73
|
+
|
|
74
|
+
### 4. 테스트 코드의 로직
|
|
75
|
+
|
|
76
|
+
```kotlin
|
|
77
|
+
@Test
|
|
78
|
+
fun `로또 번호 매칭 테스트`() {
|
|
79
|
+
val lotto = Lotto(listOf(.))
|
|
80
|
+
val winning = WinningLotto(Lotto(listOf(.)), BonusNumber(7))
|
|
81
|
+
val expected = countMatches(lotto, winning) // ⚠ 테스트가 로직 계산
|
|
82
|
+
assertThat(winning.match(lotto)).isEqualTo(expected)
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
> 테스트 코드에 가급적 "로직"을 포함하지 않는 것이 중요합니다.
|
|
87
|
+
|
|
88
|
+
→ 기댓값은 *하드코딩*. 계산하면 같은 버그가 양쪽.
|
|
89
|
+
|
|
90
|
+
### 5. Fake Constructor 미적용 → 테스트 가독성 ↓
|
|
91
|
+
|
|
92
|
+
```kotlin
|
|
93
|
+
val lotto = Lotto(listOf(LottoNumber(1), LottoNumber(2),.)) // 길게
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
→ `Lotto(1, 2, 3, 4, 5, 6)` 같은 fake constructor.
|
|
97
|
+
|
|
98
|
+
## 리뷰어 의견 요지
|
|
99
|
+
|
|
100
|
+
리뷰어 @laco-dev의 가르침:
|
|
101
|
+
|
|
102
|
+
1. **InputView + OutputView는 같은 UI 매체면 통합 가능**. CLI에서 print + readLine은 콘솔 하나.
|
|
103
|
+
|
|
104
|
+
2. **랜덤은 어떻게 뽑는지가 아닌 *무엇을 만드는지*** — 추상화 한 단계 위.
|
|
105
|
+
|
|
106
|
+
3. **함수 하나에 2가지 일 회피** — `getLottos`가 출력까지 X.
|
|
107
|
+
|
|
108
|
+
4. **테스트 기댓값 = 하드코딩**. 계산 = 같은 버그.
|
|
109
|
+
|
|
110
|
+
- **대표 인용:**
|
|
111
|
+
> 객체지향 관점으로 접근해본다면, 우리가 하고 싶은 것은 로또 번호를 생성하는 것이지 랜덤하게 뽑는 것이 아닙니다.
|
|
112
|
+
>
|
|
113
|
+
> — @laco-dev on `src/main/kotlin/lotto/model/LottoMachine.kt`
|
|
114
|
+
|
|
115
|
+
> 로또 번호를 가져오는데 OutputView에 출력까지 한다는 것을 예측하기 어렵지 않을까요?
|
|
116
|
+
>
|
|
117
|
+
> — @laco-dev on `src/main/kotlin/lotto/controller/LottoController.kt`
|
|
118
|
+
|
|
119
|
+
## 얻은 교훈
|
|
120
|
+
|
|
121
|
+
- **"무엇을 만드는지 vs 어떻게 만드는지"** — 도메인 추상화의 두 층. 도메인 객체는 *무엇*만, *어떻게*는 인터페이스 너머.
|
|
122
|
+
- **함수 하나에 2가지 일 = 함수명이 거짓말**. `getXxx + print Xxx`는 호출자 예측 불가.
|
|
123
|
+
- **테스트 기댓값 하드코딩** — 계산식이 들어가면 *프로덕션 로직의 거울*이 되어 같은 버그를 못 잡음.
|
|
124
|
+
- **CLI 환경에서 InputView vs OutputView 분리는 검토** — 같은 콘솔이면 합치는 게 자연스러울 수도.
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# PR #143 — [로또 2단계] 채넛 미션
|
|
2
|
+
|
|
3
|
+
- **Reviewee:** [@yrsel](https://github.com/yrsel)
|
|
4
|
+
- **PR:** https://github.com/woowacourse/kotlin-lotto/pull/143
|
|
5
|
+
- **단계:** 2단계 (수동 로또 추가)
|
|
6
|
+
- **리뷰어:** @laco-dev (페로로)
|
|
7
|
+
- **라인 코멘트:** 27
|
|
8
|
+
|
|
9
|
+
## 잘한 점 (설계 관점)
|
|
10
|
+
|
|
11
|
+
- **`LottoNumber` Flyweight + `from(value)`** — `(1..45).associateWith` 캐싱.
|
|
12
|
+
- **`runCatching + getOrElse`로 재시도 흐름 분기** — 비논리/논리 오류 분리 의도.
|
|
13
|
+
- **함수형 어휘 도입** (`sumOf`, `entries.sumOf`) — 누적 절차 압축.
|
|
14
|
+
- **자가 정리한 *논리/비논리 오류* 구분** — 학생 답이 리뷰어 의도와 일치, 리뷰어 칭찬.
|
|
15
|
+
|
|
16
|
+
## 못한 점 (설계 관점)
|
|
17
|
+
|
|
18
|
+
### 1. `LottoCount`가 *Validator* 역할 — 예외로 흐름 제어
|
|
19
|
+
|
|
20
|
+
```kotlin
|
|
21
|
+
data class LottoCount(val number: Int) {
|
|
22
|
+
init { require(number >= 0) { ERROR_NEGATIVE_COUNT } }
|
|
23
|
+
fun validateLottoCount(lottoCount: LottoCount) {
|
|
24
|
+
require(isAvailPurchaseLottoCount(lottoCount)) { ERROR_EXCEED_LOTTO_COUNT }
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
리뷰어: "LottoCount의 역할은 Validator가 아닙니다. 우리가 알고 싶은 기능은 로또를 몇 장 살 수 있는지가 아닐까요? 그렇다면, 예외를 발생시키는 대신 *구입 가능한지 여부를 판단*하는 기능을 만들어 보는 게 좋을 것 같아요." — Boolean 반환 + 호출자 분기.
|
|
30
|
+
|
|
31
|
+
### 2. `isPositive()` — 도달 불가능한 조건의 분기
|
|
32
|
+
|
|
33
|
+
```kotlin
|
|
34
|
+
fun isPositive(): Boolean = number > 0
|
|
35
|
+
// 사용처
|
|
36
|
+
if (manualLottoCount.isPositive()) outputView.printManualLottoNumbersGuide()
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
리뷰어: "LottoCount가 논리적으로 항상 0보다 크도록 작성하였어요. 그렇다면 isPositive()라는 개념이 필요할까요?"
|
|
40
|
+
|
|
41
|
+
### 3. `data class LottoCount(private var _number: Int)` — readOnly 위반
|
|
42
|
+
|
|
43
|
+
```kotlin
|
|
44
|
+
data class LottoCount(private var _number: Int) {
|
|
45
|
+
val number = _number
|
|
46
|
+
init { if (_number < 0) _number = 0 }
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
리뷰어: "논리적으로 LottoCount가 0이 될 수 없다는 점을 지키기 위해 불변 클래스로 만드는 연습이 필요할 것 같네요! data class는 기본적으로 ReadOnly를 지향합니다. 그렇기 때문에 내부적으로 상태를 변경시키는 방식이 아닌. 적절한 구현을 통해 이를 유지하게 됩니다." 학생: "*예외를 발생시키지 않는다*에 홀렸나봐요. require를 통해 예외 처리 하지 말라는 의미로 잘못 해석."
|
|
51
|
+
|
|
52
|
+
### 4. `InputView`가 `OutputView` 참조
|
|
53
|
+
|
|
54
|
+
```kotlin
|
|
55
|
+
class InputView {
|
|
56
|
+
private val outputView = OutputView()
|
|
57
|
+
private fun readLottoNumbersWithGuideMessage(guideMessage: () -> Unit): List<LottoNumber> {
|
|
58
|
+
guideMessage()
|
|
59
|
+
.
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
리뷰어: "콘솔에 출력하는 것을 반드시 OutputView만 해야 하는 것인가요?" + "guideMessage()가 뭘 하고 싶은 건지 의도가 잘 드러나는 이름인가요? 저는 상태처럼 느껴지는데요!" — *역할 분리에 매몰*해 *람다 + 의도 모호 명명* 발생. 후속: "InputView와 OutputView가 역할을 명확하게 나누려고 하다 보니 어색하지만 실제로는 구분을 하지 않고 하나의 개념으로 사용이 되고는 합니다."
|
|
65
|
+
|
|
66
|
+
### 5. 함수형 압축이 *가독성 좋은가*
|
|
67
|
+
|
|
68
|
+
```kotlin
|
|
69
|
+
private fun getTotalPrize(): Double =
|
|
70
|
+
rankStatistics.asIterable().sumOf { (rank, count) -> rank.prizeMoney * count }.toDouble()
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
리뷰어: "함수형 프로그래밍이 코드 작성에 편리한 부분을 제공해 주는 점은 맞지만. 한편으로는 가독성 관점에서 비교하면 아쉬운 점이 많을 때도 있어요. 어떤 점이 좋아졌다고 생각하시는지 궁금합니다!"
|
|
74
|
+
|
|
75
|
+
### 6. *모든 변환 실패 = 예외* — 학생 자가 학습
|
|
76
|
+
|
|
77
|
+
학생 자가 학습: "예외로 모든 문제를 해결하려는 습관이 있었던 것 같습니다." 리뷰어: "쉬운 힌트를 드려보면 *테스트를 작성해야 한다는 생각이 마구마구 솟는다면 == 논리적인 오류*입니다. 그렇지 않고 코드를 작성하다가 누가 봐도 문제는 없어 보인다면 no-op을 하거나 코드가 자연스럽게 이어지도록 적당히 처리를 하고는 합니다."
|
|
78
|
+
|
|
79
|
+
### 7. `from`/`of`/`valueOf` 학생 정리
|
|
80
|
+
|
|
81
|
+
학생: "`from`: 하나의 매개변수, `of`: 여러 매개변수, `valueOf`: 객체 생성에 의미 부여."
|
|
82
|
+
|
|
83
|
+
## 리뷰어 의견 요지
|
|
84
|
+
|
|
85
|
+
- **객체에 *Validate*가 아니라 *Predicate*** — Boolean 반환으로 호출자가 분기.
|
|
86
|
+
- **data class = ReadOnly 지향** — *force-set*이 아니라 *불가능한 입력을 거절*.
|
|
87
|
+
- **역할 분리에 과몰입 회피** — InputView/OutputView를 *기능적으로 묶을 수도 있음*.
|
|
88
|
+
- **함수형 도입 = *가독성 명시화* 의무** — 자기 코드의 *장점*을 말로 할 수 있어야.
|
|
89
|
+
- **논리적 오류 판별 = 테스트 작성 충동**.
|
|
90
|
+
|
|
91
|
+
- **대표 인용:**
|
|
92
|
+
> LottoCount의 역할은 Validator가 아닙니다. 우리가 알고 싶은 기능은 로또를 몇 장 살 수 있는지가 아닐까요?
|
|
93
|
+
> — @laco-dev on `src/main/kotlin/lotto/controller/LottoController.kt`
|
|
94
|
+
|
|
95
|
+
> data class는 기본적으로 ReadOnly를 지향합니다. … 내부적으로 상태를 변경시키는 방식이 아닌. 적절한 구현을 통해 이를 유지하게 됩니다.
|
|
96
|
+
> — @laco-dev on `src/main/kotlin/lotto/model/LottoCount.kt`
|
|
97
|
+
|
|
98
|
+
> 쉬운 힌트를 드려보면 *테스트를 작성해야 한다는 생각이 마구마구 솟는다면 == 논리적인 오류*입니다.
|
|
99
|
+
> — @laco-dev on `README.md`
|
|
100
|
+
|
|
101
|
+
## 얻은 교훈
|
|
102
|
+
|
|
103
|
+
- **Validator 메서드는 *Predicate*로** — `validate*` (예외 던지기)보다 `is*`/`can*` (Boolean 반환)이 호출자에 자유.
|
|
104
|
+
- **data class는 *ReadOnly 지향*** — `var` + `init { if(.) set }`로 *나쁜 상태*를 *조용히 정정*하지 말고, *나쁜 입력을 거절*.
|
|
105
|
+
- **역할 분리는 *비용*이 있다** — InputView가 OutputView를 알지 않으려는 노력이 *람다 + 의도 모호 명명*을 만들면 분리의 이점 소멸.
|
|
106
|
+
- **함수형 어휘는 *가독성 명시화*가 필수** — 도입하면 *왜 이게 더 읽기 좋은가*를 말로 할 수 있어야.
|
|
107
|
+
- **테스트 충동 = 논리적 오류 신호**. 비논리적(형식)은 *조용히 재시도*, 논리적(비즈니스)은 *명시적 처리* + 테스트.
|
|
108
|
+
- **`from`/`of`/`valueOf` 명명 규칙** — 1개면 `from`, 여러 개면 `of`, 의미 부여면 `valueOf`.
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# PR #33 — [멧돼지] 코틀린 자동차 경주 제출합니다
|
|
2
|
+
|
|
3
|
+
- **Reviewee:** [@2chang5](https://github.com/2chang5)
|
|
4
|
+
- **PR:** https://github.com/woowacourse/kotlin-racingcar/pull/33
|
|
5
|
+
- **단계:** 1단계
|
|
6
|
+
- **리뷰어:** @BeokBeok
|
|
7
|
+
- **라인 코멘트:** 27
|
|
8
|
+
|
|
9
|
+
## 잘한 점 (설계 관점)
|
|
10
|
+
|
|
11
|
+
- **`NumberGenerator` 전략 패턴 + `StubNumberGenerator` 도입** — 리뷰어 명시적 칭찬. 테스트 결정성 확보.
|
|
12
|
+
- **의존성 주입 적용** — RacingGame이 NumberGenerator를 주입받는 구조.
|
|
13
|
+
- **`Referee` 분리로 우승자 판별 책임 별도화**.
|
|
14
|
+
- **자기 의문을 적극적으로 표현** — runCatching, drop 함수, 상수 위치 등에 대해 깊은 토론.
|
|
15
|
+
|
|
16
|
+
## 못한 점 (설계 관점)
|
|
17
|
+
|
|
18
|
+
- **`Const.kt` / `GameRule.kt`로 상수를 일반 파일로 모음** — 결합도 증가. 특정 클래스에서만 쓰는 상수는 companion으로.
|
|
19
|
+
- **`RacingCar.getName()` 자바 스타일 게터** — 코틀린 프로퍼티 직접 노출이 자연스러움.
|
|
20
|
+
- **`StubNumberGenerator`가 `MutableList` 받음** — 외부 수정에 무방비. 방어적 복사 누락.
|
|
21
|
+
- **우승자 로직이 Controller에** — 책임 자리 어긋남. 별개 객체로.
|
|
22
|
+
- **try-catch 사용 (indent depth 제한으로 인한 우회)** — runCatching의 표준 사용을 위한 함수 분리 미적용.
|
|
23
|
+
- **`OutputView` 클래스 내부 상수가 public** — private 가시성 누락.
|
|
24
|
+
- **테스트 이름 추상화** — "정상적으로 작동한다"는 무엇이 어떤 상태인지 안 드러냄.
|
|
25
|
+
|
|
26
|
+
## 리뷰어 의견 요지
|
|
27
|
+
|
|
28
|
+
리뷰어 @BeokBeok는 **방어적 복사** 라는 객체지향 핵심 패턴을 정확히 안내. MutableList를 받으면 외부 수정에 무방비 → 무결성 깨짐. Immutable 타입 + 방어적 복사로 안전성.
|
|
29
|
+
|
|
30
|
+
또한 **backing property** 패턴을 명시적으로 가르침 — `_movingState`(private) + `get() = _movingState`(public)로 코틀린 프로퍼티의 게터를 활용.
|
|
31
|
+
|
|
32
|
+
상수 위치에 대해서는 **"특정 클래스에서만 쓰면 companion으로"** 라는 명확한 가이드. 학생이 "각 사용처 vs 별도 파일" 중 어느 것이 맞는지 직접 물어봐 정답을 받음.
|
|
33
|
+
|
|
34
|
+
`indent depth 2 제한`으로 try-catch를 쓸 수밖에 없었다는 학생 답변에 대해 **"함수로 분리"** 라는 깔끔한 응답 — 제약을 우회의 핑계로 두지 말고 설계로 풀어내라는 가이드.
|
|
35
|
+
|
|
36
|
+
- **대표 인용:**
|
|
37
|
+
> Mutable타입을 사용하게 되면, 외부에서 데이터를 변경하게 되면 의도치 않게 내부의 데이터가 변경되어 무결성이 깨지게 돼요. 외부에서 데이터를 변경할 수 없도록, List타입을 활용해보면 어떨까요?
|
|
38
|
+
>
|
|
39
|
+
> — @BeokBeok on `src/main/kotlin/racingcar/domain/numbergenerator/StubNumberGenerator.kt`
|
|
40
|
+
|
|
41
|
+
> 정의한 상수들은 특정 클래스에서만 사용하고 있네요. 그렇다면 사용하는 클래스의 companion object를 활용해보면 어떨까요?
|
|
42
|
+
>
|
|
43
|
+
> — @BeokBeok on `src/main/kotlin/racingcar/constant/GameRule.kt:6`
|
|
44
|
+
|
|
45
|
+
> indent depth가 2가 넘어간다면, 함수로 분리해보면 어떨까요?
|
|
46
|
+
>
|
|
47
|
+
> — @BeokBeok on `src/main/kotlin/racingcar/view/InputView.kt:9`
|
|
48
|
+
|
|
49
|
+
## 얻은 교훈
|
|
50
|
+
|
|
51
|
+
- **방어적 복사의 원리.** 외부에서 받은 컬렉션을 내부 상태로 사용한다면, 외부가 그 컬렉션을 바꿔도 내부가 안전해야. `MutableList`를 받아 내부에 그대로 저장하면 외부 변경이 즉시 내부에 전파.
|
|
52
|
+
- **상수의 자리는 사용 응집도가 결정.** 특정 클래스에서만 쓰면 그 클래스의 companion으로. 두세 도메인이 공유하면 각자에게 복제하거나 공유 도메인 객체로. 절대 `Constants.kt` 한 곳으로 모으지 말 것.
|
|
53
|
+
- **Backing property로 코틀린 프로퍼티 활용.** `private _x` + `val x get() = _x` 패턴으로 자바 게터를 만들지 않고도 read-only 외부 노출.
|
|
54
|
+
- **제약은 우회가 아니라 설계로 풀어낸다.** "indent depth 2 제한"이 있으면 함수 분리로. 제약을 핑계로 표준 도구(runCatching)를 못 쓴다고 결론짓지 말 것.
|
|
55
|
+
- **테스트 이름의 명세화.** "정상적으로 작동한다" → "4 이상이면 전진한다", "이름은 5자 이하만 허용" 같은 명세 단위로.
|
|
56
|
+
- **자기 의문 응답 패턴이 학습 가속.** 학생이 "drop이 List 반환인데 Int 반환이 맞나요?" 물어보면 리뷰어가 자기 잘못 인정("코드를 잘못 봤네요")하고 학생의 방향을 칭찬. 진솔한 토론이 학습 사이클을 만든다.
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# PR #75 — [멧돼지] 2단계 자동차 경주 제출합니다
|
|
2
|
+
|
|
3
|
+
- **Reviewee:** [@2chang5](https://github.com/2chang5)
|
|
4
|
+
- **PR:** https://github.com/woowacourse/kotlin-racingcar/pull/75
|
|
5
|
+
- **단계:** 2단계
|
|
6
|
+
- **리뷰어:** @BeokBeok
|
|
7
|
+
- **라인 코멘트:** 14
|
|
8
|
+
|
|
9
|
+
## 잘한 점 (설계 관점)
|
|
10
|
+
|
|
11
|
+
- **`Cars` 일급 컬렉션 도입**.
|
|
12
|
+
- **정적 팩토리 메서드 적용 시도** — companion object 활용.
|
|
13
|
+
- **InputView의 검증 책임을 Controller로 이전** — InputView의 책임을 좁힘.
|
|
14
|
+
- **예외 처리 학습 의지** — 리뷰어의 자료를 적극 흡수, 추가 학습 자료 요청.
|
|
15
|
+
|
|
16
|
+
## 못한 점 (설계 관점)
|
|
17
|
+
|
|
18
|
+
- **`Cars(names: List<String>)` 시그니처 - 클래스명과 캡슐화 대상 어긋남** — "여러 대의 자동차"인데 받는 것은 "이름". 클래스가 캡슐화하는 게 무엇인지 명확하지 않음.
|
|
19
|
+
- **backing property를 잘못된 자리에 적용** — `_value`를 외부에서 변경 안 하는데도 굳이 사용. 표준 val로 충분.
|
|
20
|
+
- **`MutableList` 패턴 잔존** — 1단계 학습 반복.
|
|
21
|
+
- **올바른 입력까지 함수 재호출** — Exception을 흐름 제어로 사용. 요구사항에 없는 동작인데 자체적으로 구현.
|
|
22
|
+
- **테스트명에 "테스트" 단어 포함** — 클래스 자체가 Test이므로 중복.
|
|
23
|
+
- **테스트 이름의 도메인 추상화 미흡** — "출력 양식"이 무엇인지 안 드러남.
|
|
24
|
+
|
|
25
|
+
## 리뷰어 의견 요지
|
|
26
|
+
|
|
27
|
+
리뷰어 @BeokBeok는 **예외 처리의 두 종류** 라는 큰 주제를 명확히 가르침: (1) 오류가 예상되는 경우 → null 또는 기본값, (2) 오류가 예상되지 않는 경우 → Exception throw. 학생이 입력 재시도용 Exception을 흐름 제어로 쓰는 것을 정확히 짚음. Elizarov의 아티클까지 공유.
|
|
28
|
+
|
|
29
|
+
또한 **요구사항 분석의 중요성** — "올바른 값이 입력될 때까지 프로그램이 종료되지 않는다"는 요구가 없는데 학생이 자체 구현. 요구사항을 정확히 파악하는 것이 안정적 프로그램 구현보다 우선.
|
|
30
|
+
|
|
31
|
+
`Cars` 시그니처 어긋남에 대해 **"클래스가 캡슐화하는 대상을 명확히"** 라는 가이드. 이름 리스트가 아닌 RacingCar 리스트를 받는 게 자연스러움. 다른 입력으로 만들고 싶다면 팩토리 메서드.
|
|
32
|
+
|
|
33
|
+
- **대표 인용:**
|
|
34
|
+
> 클래스명만 봤을 때에는 "여러 대의 자동차"를 의미하지만, 생성자로 캡슐화한 값은 "자동차의 이름"입니다. 클래스가 캡슐화하고자 하는 프로퍼티를 캡슐화해보면 어떨까요?
|
|
35
|
+
>
|
|
36
|
+
> — @BeokBeok on `src/main/kotlin/racingcar/domain/Cars.kt`
|
|
37
|
+
|
|
38
|
+
> 오류가 예상되는 경우에는 주로 null 또는 기본값을 리턴합니다. 반면, 오류가 예상되지 않는 경우에는 Exception을 throw하도록 합니다. ... Exception은 반드시 예외적인 상황에서만 사용하는 것이 좋습니다.
|
|
39
|
+
>
|
|
40
|
+
> — @BeokBeok on `src/main/kotlin/racingcar/domain/RacingGame.kt:42`
|
|
41
|
+
|
|
42
|
+
> 본 미션의 요구사항에는 "올바른 값이 입력될때까지 프로그램이 종료되지 않는다."와 같은 항목은 없습니다. 안정적인 프로그램을 만드는 것도 좋지만, 요구사항을 잘 분석하는 것도 못지않게 중요합니다.
|
|
43
|
+
>
|
|
44
|
+
> — @BeokBeok on `src/main/kotlin/racingcar/domain/RacingGame.kt:42`
|
|
45
|
+
|
|
46
|
+
## 얻은 교훈
|
|
47
|
+
|
|
48
|
+
- **예외는 진짜 예외 상황에만.** 흐름 제어(루프, 재시도, 입력 검증 등)에 예외를 쓰면 코드가 느려지고 의도가 흐려진다. 예상되는 오류는 null/기본값/Result로, 진짜 예상 못한 상황만 Exception.
|
|
49
|
+
- **요구사항 분석이 코딩의 시작.** 코드를 더 견고하게 만드는 것보다 요구사항을 정확히 이해하는 것이 더 가치 있는 경우가 많다. 자체 판단 확장은 위험할 수 있음.
|
|
50
|
+
- **클래스 캡슐화의 일관성.** `Cars`라는 이름이 "여러 자동차"라면 그 자동차들의 리스트를 받아야. 이름 리스트는 다른 의미. 팩토리 메서드로 변환 진입점을 제공.
|
|
51
|
+
- **backing property는 도구이지 패턴이 아니다.** 외부 변경을 막고 싶을 때만 사용. 단순 val로 충분한 자리에 backing property를 쓰면 불필요한 복잡도.
|
|
52
|
+
- **요구사항 외 자체 구현의 위험.** 학생이 "입력 재시도"를 자체적으로 구현했지만 요구사항에 없는 동작. 자기 판단 추가는 학습 가치가 있지만 요구사항 일치를 우선.
|
|
53
|
+
- **자료 추천 → 학생 흡수 → 추가 요청 → 리뷰어 응답** 의 학습 사이클이 매우 깊다. 단순 코드 수정보다 학습 자료 공유가 더 큰 가치를 만든다.
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# PR #85 — [자동차 경주] 주노 미션 제출
|
|
2
|
+
|
|
3
|
+
- **Reviewee:** [@CFalws](https://github.com/CFalws) (주노)
|
|
4
|
+
- **PR:** https://github.com/woowacourse/kotlin-racingcar/pull/85
|
|
5
|
+
- **단계:** 2단계 (단일 PR)
|
|
6
|
+
- **리뷰어:** @Choisehyeon
|
|
7
|
+
- **라인 코멘트:** 21
|
|
8
|
+
|
|
9
|
+
## 잘한 점 (설계 관점)
|
|
10
|
+
|
|
11
|
+
- **Car, Cars, RacingGame 도메인 분리** — 책임 분배 시도.
|
|
12
|
+
- **`NumberGenerator` 추상화** — 테스트 가능성.
|
|
13
|
+
- **`require()` 활용한 도메인 무결성 검증** — 입력값 invariant 표현.
|
|
14
|
+
- **`repeat` 활용한 trialCount 흐름** — 가변 카운터 제거.
|
|
15
|
+
- **리뷰어 제안에 대해 *자기 근거*로 거부할 줄 알기** — 에러 메시지 상수화 거절 ("로직 흐름에서 메시지가 바로 읽히는 것이 가독성").
|
|
16
|
+
|
|
17
|
+
## 못한 점 (설계 관점)
|
|
18
|
+
|
|
19
|
+
- **Controller가 `trialCount` 상태 보유 + 검증까지** — 학생이 PR에 직접 우려 표명.
|
|
20
|
+
- **`Car.position`이 var (외부 변경 가능)** — `private set` 누락. 리팩토링 후에도 다시 빠뜨림.
|
|
21
|
+
- **`name.trim()` 같은 정규화 로직을 주 생성자 안에서 처리** — 부 생성자 / 팩토리 메서드 후보.
|
|
22
|
+
- **`maxOf` vs `maxBy` 혼동**.
|
|
23
|
+
- **코딩 컨벤션 (클래스 멤버 순서) 산발적 비준수**.
|
|
24
|
+
|
|
25
|
+
## 리뷰어 의견 요지
|
|
26
|
+
|
|
27
|
+
리뷰어 @Choisehyeon은 **"코틀린 idiom + 도메인 캡슐화"**를 함께 강조하지만, 본 분석에서는 OOP 부분에 집중.
|
|
28
|
+
|
|
29
|
+
1. **position 캡슐화** — `var position`은 외부 변경 가능. `private set` 또는 `val` + 새 Car 반환.
|
|
30
|
+
|
|
31
|
+
2. **에러 메시지 상수화 토론** — 학생 거부: "로직 흐름에서 메시지가 바로 읽혀 가독성 좋다. 여러 곳에서 같은 에러가 발생하면 그때 상수화." → 리뷰어 수용: "안 해주는 게 더 로직 흐름에서 읽기 좋을 것 같다."
|
|
32
|
+
|
|
33
|
+
3. **trim() 같은 정규화 = 팩토리 함수의 자리** — 주 생성자가 "받은 그대로 저장"이라면, 정규화는 팩토리에서. invariant와 normalization을 섞지 말 것.
|
|
34
|
+
|
|
35
|
+
4. **trialCount 검증의 위치** — 학생이 "Controller가 trialCount 상태 + 검증까지 갖는 게 우려된다"고 자가 인식. 도메인 모델링의 미해결 과제.
|
|
36
|
+
|
|
37
|
+
- **대표 인용:**
|
|
38
|
+
> 컨트롤러가 trialCount라는 상태를 가지고 검증까지 수행하는 것이 너무 많은 역할을 가지는건 아닐까 우려되기도 합니다 😂
|
|
39
|
+
>
|
|
40
|
+
> — @CFalws (학생 자신) on `src/main/kotlin/racingcar/domain/RacingGame.kt`
|
|
41
|
+
|
|
42
|
+
> 저는 개인적으로 로직의 흐름에서 메시지가 바로 읽히는것이 가독성이 좋다고 생각되어 상수화를 해주지 않았습니다
|
|
43
|
+
>
|
|
44
|
+
> — @CFalws on `src/main/kotlin/racingcar/domain/Car.kt:13`
|
|
45
|
+
|
|
46
|
+
> name을 trim() 하기 위해 이렇게 구현하신 것 같은데 부생성자나 팩토리 함수를 사용해보시는 것은 어떨까요?
|
|
47
|
+
>
|
|
48
|
+
> — @Choisehyeon on `src/main/kotlin/racingcar/domain/Car.kt`
|
|
49
|
+
|
|
50
|
+
## 얻은 교훈
|
|
51
|
+
|
|
52
|
+
- **리뷰어 제안에 자기 근거로 거부할 줄 알기.** "상수화하라"는 제안에 "로직 흐름의 가독성" 근거로 거부 → 리뷰어 수용. 모든 제안을 따르는 게 아니라 *자기 기준*으로 판단. 리뷰는 토론.
|
|
53
|
+
- **정규화(trim, lowercase)는 팩토리 함수의 자리.** 주 생성자는 "받은 invariant 그대로". 입력 정제는 객체 생성 전. 두 가지를 섞으면 "이 객체가 생성될 때 입력이 어떻게 변형되는가"가 불투명.
|
|
54
|
+
- **자가 의문도 PR에 적자.** "Controller가 너무 많은 일을 하는 것 같다"를 PR에 적으면 리뷰어가 그 의문을 함께 검증. 자기검증의 흔적은 다음 라운드의 출발점.
|
|
55
|
+
- **`var position`은 도메인에서 거의 항상 잘못된 신호.** 외부에서 변경 가능한 도메인 상태는 invariant를 깨뜨릴 위험. `private set` 또는 immutable + 새 인스턴스 반환.
|
|
56
|
+
- **trial count의 책임 = "게임 진행 횟수"는 RacingGame 도메인 안에**. Controller가 카운터를 들고 있다는 것은 도메인의 일부가 Controller에 누수된 신호.
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# PR #46 — [자동차 경주] 콩이 미션 제출합니다
|
|
2
|
+
|
|
3
|
+
- **Reviewee:** [@Choisehyeon](https://github.com/Choisehyeon)
|
|
4
|
+
- **PR:** https://github.com/woowacourse/kotlin-racingcar/pull/46
|
|
5
|
+
- **단계:** 1단계 (단일 PR)
|
|
6
|
+
- **리뷰어:** @galcyurio
|
|
7
|
+
- **라인 코멘트:** 16
|
|
8
|
+
|
|
9
|
+
## 잘한 점 (설계 관점)
|
|
10
|
+
|
|
11
|
+
- **`Cars`, `Car`, `NumberGenerator`, `Validator` 분리**.
|
|
12
|
+
- **테스트 더블 (FakeGenerator) 작성**.
|
|
13
|
+
- **`RandomGenerator` 인터페이스 활용**.
|
|
14
|
+
|
|
15
|
+
## 못한 점 (설계 관점)
|
|
16
|
+
|
|
17
|
+
- **`Cars`가 `List<Car>` 생성자가 아닌 다른 형태** — 일급 컬렉션의 표준 패턴 미준수.
|
|
18
|
+
- **`Cars.move()`가 차량 한 대씩 호출하는 방식** — 컬렉션 객체에 "전체 움직임" 메시지가 자연스러움.
|
|
19
|
+
- **`name`, `position` getter 노출** — 외부에서 그 값으로 로직 수행, Car가 자기 일을 안 함.
|
|
20
|
+
- **`Validator` 검증을 도메인 객체로 안 옮김**.
|
|
21
|
+
- **`generate()` 대신 `generateNumber()` 같은 중복 명명**.
|
|
22
|
+
- **`RandomGenerator` 이름이 `RandomNumberGenerator`였어야**.
|
|
23
|
+
- **테스트 케이스 이름이 추상적** — "정상 동작한다" 류.
|
|
24
|
+
- **내부 List를 외부에 그대로 노출** — 방어적 복사 미적용.
|
|
25
|
+
|
|
26
|
+
## 리뷰어 의견 요지
|
|
27
|
+
|
|
28
|
+
리뷰어 @galcyurio의 핵심 메시지:
|
|
29
|
+
|
|
30
|
+
1. **일급 컬렉션 = `List<Car>` 생성자 + `get()` override + companion object 팩토리** — 일급 컬렉션의 정석 패턴.
|
|
31
|
+
|
|
32
|
+
2. **getter는 사실상 캡슐화 미적용** — "name, position을 외부에서 쓰는 로직을 그대로 Car에서 처리하도록." Tell Don't Ask.
|
|
33
|
+
|
|
34
|
+
3. **방어적 복사** — 내부 컬렉션 노출 시 `toList()`로 새 List 반환. 외부 변경으로부터 보호.
|
|
35
|
+
|
|
36
|
+
4. **테스트 케이스 본문 = 의도가 본문만 봐도 보임** — "pobi, gugu가 *왜* 이기는지 본문만 봐도 알 수 있게."
|
|
37
|
+
|
|
38
|
+
5. **함수명 = 컨텍스트 + 행위, 중복 제거** — `NumberGenerator.generate()`로 충분. `NumberGenerator.generateNumber()`는 컨텍스트 중복.
|
|
39
|
+
|
|
40
|
+
6. **예외 처리 4단 원칙** (Effective Kotlin Item 7).
|
|
41
|
+
|
|
42
|
+
- **대표 인용:**
|
|
43
|
+
> getter를 선언한 것과 다름이 없습니다. name, position을 외부에서 사용하는 곳의 로직을 그대로 Car에서 처리하도록 만들어보세요. 그러고도 필요한 경우가 생긴다면 필드를 그대로 공개해주셔도 좋습니다.
|
|
44
|
+
>
|
|
45
|
+
> — @galcyurio on `src/main/kotlin/model/Car.kt`
|
|
46
|
+
|
|
47
|
+
> Cars.move() 함수이므로 모든 차량을 한 번에 움직이도록 만들어보면 어떨까요? 그리고 외부로는 그 결과를 어떻게 공유할 수 있을까요?
|
|
48
|
+
>
|
|
49
|
+
> — @galcyurio on `src/main/kotlin/model/Cars.kt`
|
|
50
|
+
|
|
51
|
+
> 내부 필드를 외부에 공개할 때는 toList()를 통해 방어적 복사를 한 이후에 넘겨주세요.
|
|
52
|
+
>
|
|
53
|
+
> — @galcyurio on `src/main/kotlin/model/Cars.kt`
|
|
54
|
+
|
|
55
|
+
## 얻은 교훈
|
|
56
|
+
|
|
57
|
+
- **일급 컬렉션 표준 패턴**: 단일 `List<T>` 필드 + 생성자에서 받기 + `get()`/`size` override + companion object 팩토리.
|
|
58
|
+
- **getter 선언 ≈ 캡슐화 안 함**. 같은 효과. 진짜 캡슐화는 "외부 로직을 객체 안으로 가져오기" — Tell Don't Ask.
|
|
59
|
+
- **방어적 복사 = 컬렉션 노출의 의무**. 내부 List를 노출하면 외부에서 `add()`로 도메인 invariant 깨질 수 있음. `toList()` / `unmodifiableList`로.
|
|
60
|
+
- **테스트 코드의 *의도*는 본문에서 보여야**. 테스트 함수명도 중요하지만, 본문만 봐도 "왜 이 결과가 나오는가"가 명확해야.
|
|
61
|
+
- **`Cars.move()`의 *반환값* 설계**. 차량을 다 움직인 후 결과를 어떻게 외부에 보여줄까 — 새 Cars 반환? 결과 List<Position>? "외부와의 결과 공유" 방식이 일급 컬렉션 design의 일부.
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# PR #49 — [코건] 코틀린 자동차 경주 제출합니다
|
|
2
|
+
|
|
3
|
+
- **Reviewee:** [@DYGames](https://github.com/DYGames)
|
|
4
|
+
- **PR:** https://github.com/woowacourse/kotlin-racingcar/pull/49
|
|
5
|
+
- **단계:** 1단계 (단일 PR이지만 풍부한 라운드)
|
|
6
|
+
- **리뷰어:** @namjackson
|
|
7
|
+
- **라인 코멘트:** 42
|
|
8
|
+
|
|
9
|
+
## 잘한 점 (설계 관점)
|
|
10
|
+
|
|
11
|
+
- **`Name`/`Position` 값 객체로 원시 강박 해소** — 도메인 어휘 충실.
|
|
12
|
+
- **`compareByPosition` 이름 변경** — 비교 기준이 시그니처에 드러나도록.
|
|
13
|
+
- **생성자 주입 방식 적용 후 테스트 격리** — 리뷰어 명시적 칭찬.
|
|
14
|
+
- **NumberGenerator 인터페이스 도입 + SequentialNumberGenerator로 테스트 결정성 확보**.
|
|
15
|
+
- **방어적 복사 적용** — 리뷰어 명시적 칭찬.
|
|
16
|
+
- **리뷰 적극 흡수 후 광범위 리팩터링** — Util 제거, Values 분해, lateinit 제거, for→map 전환 등.
|
|
17
|
+
|
|
18
|
+
## 못한 점 (설계 관점)
|
|
19
|
+
|
|
20
|
+
- **초기 `Util.kt`로 잡다한 기능 묶음** — Wolrd 객체와 강한 의존. 클래스 사용처가 한 곳에 결합.
|
|
21
|
+
- **`Values.kt`로 상수 한 곳에 모음** — Constants 안티패턴.
|
|
22
|
+
- **`Name.name` 같은 중복 식별자** — `value`가 더 자연스러움.
|
|
23
|
+
- **`Position`에 View 관련 로직 일부 포함** — 도메인이 표시를 알게 됨.
|
|
24
|
+
- **`CarManager`라는 -er Manager 명사** — 일급 컬렉션(`Cars`)이 더 어울리는 자리.
|
|
25
|
+
- **`CarManager`가 가변 컬렉션 + lateinit + 초기화 분리 시점 risk** — 초기화 전 호출 위험.
|
|
26
|
+
- **테스트만을 위한 메서드 공개** — `RacingManager`의 일부 함수.
|
|
27
|
+
- **`determineWinner` 테스트가 init/step 등에 의존** — 테스트 격리 부족.
|
|
28
|
+
- **`SequentialNumberGenerator`가 production 패키지에 위치** — 테스트 패키지로 옮겨야.
|
|
29
|
+
- **테스트 이름 추상화** — "자동차 전진 테스트"같은 표현보다 구체적 케이스명 필요.
|
|
30
|
+
|
|
31
|
+
## 리뷰어 의견 요지
|
|
32
|
+
|
|
33
|
+
리뷰어 @namjackson는 일관되게 **"이름이 동작을 정확히 약속해야 한다"** 와 **"테스트 격리 = 책임 분리의 거울"** 을 짚었다.
|
|
34
|
+
|
|
35
|
+
`quit` 함수가 사실은 결과를 출력하는 코드, `compareTo`가 사실은 position 비교 등 — 이름과 동작의 어긋남을 정밀하게 찾아냄.
|
|
36
|
+
|
|
37
|
+
`Util` 클래스에 대해서는 **"강한 의존성 + 모호한 범위 → 다른 방법 고민"** 이라는 명확한 가이드. 학생이 이를 적극 반영해 Util을 해체한 것이 큰 학습 산출물.
|
|
38
|
+
|
|
39
|
+
테스트 측면에서는 (1) **생성자 주입으로 격리**, (2) **다른 함수에 의존하지 않는 초기화**, (3) **테스트용 코드는 테스트 패키지** 세 가지를 정밀하게.
|
|
40
|
+
|
|
41
|
+
- **대표 인용:**
|
|
42
|
+
> 함수의 이름은 quit이지만, 실제로는 레이싱의 결과, 우승자를 선정하여 출력하고 있네요!
|
|
43
|
+
>
|
|
44
|
+
> — @namjackson on `src/main/kotlin/racingcar/controller/World.kt`
|
|
45
|
+
|
|
46
|
+
> Util을 사용하는 클래스와의 강한 의존성이 생기기도 하고 ( Wolrd 객체 ) Util이라는 모호한 범위의 객체라 관리하기도 힘들어지는것 같단 생각이 들어요. 다른 방법을 고민해보셔도 좋을거같아요.
|
|
47
|
+
>
|
|
48
|
+
> — @namjackson on `src/main/kotlin/racingcar/misc/Util.kt`
|
|
49
|
+
|
|
50
|
+
> 우승자 결정 테스트로 carManager.determineWinner()에 대한 테스트임에도 불구하고, carManager의 init, step 등의 함수들이 호출되고있습니다. determineWinner이지만, carManager의 init, step 함수의 의존하고 있는 테스트 코드입니다.
|
|
51
|
+
>
|
|
52
|
+
> — @namjackson on `src/test/kotlin/racingcar/model/CarManagerTest.kt`
|
|
53
|
+
|
|
54
|
+
## 얻은 교훈
|
|
55
|
+
|
|
56
|
+
- **이름과 동작의 일치 검증법:** 함수 이름만 보고 본문을 예측해보고, 실제 본문과 일치하는지 확인. 어긋나면 이름이 거짓말하거나 함수가 두 가지 일을 하는 신호.
|
|
57
|
+
- **Util은 안티패턴의 결정체.** (1) 강한 의존성, (2) 모호한 범위, (3) 응집도 없는 묶음, (4) 변경 영향 광범. 학생이 Util을 해체한 과정 자체가 강력한 학습.
|
|
58
|
+
- **테스트 격리 = 다른 메서드 비의존.** 한 함수의 테스트가 같은 클래스의 다른 함수를 거쳐야 한다면, 그 함수는 사실 별개 책임. 생성자 주입으로 상태를 직접 만들면 격리.
|
|
59
|
+
- **`Manager`/`Handler`/`Util` 같은 절차 명사 회피.** 그 행위의 진짜 도메인 명사를 찾으면 객체지향다워진다. `CarManager` → `Cars` (일급 컬렉션).
|
|
60
|
+
- **방어적 복사 = 외부 변경 차단.** 리스트나 컬렉션을 받아 내부 상태로 사용할 때 외부가 그 컬렉션을 바꿔도 내부가 안전하게.
|
|
61
|
+
- **테스트용 코드는 테스트 패키지.** `SequentialNumberGenerator`가 production에 있으면 production 의존 그래프 오염. test/ 하위로.
|
|
62
|
+
- **42개 코멘트 PR의 광범위 리팩터링** — 학생이 거의 모든 코멘트를 흡수해 다음 라운드를 안 만들고 한 번에 정리. 매우 깊은 학습 사이클.
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# PR #40 — [자동차 경주] 에밀리 미션 제출합니다
|
|
2
|
+
|
|
3
|
+
- **Reviewee:** [@EmilyCh0](https://github.com/EmilyCh0)
|
|
4
|
+
- **PR:** https://github.com/woowacourse/kotlin-racingcar/pull/40
|
|
5
|
+
- **단계:** 1단계
|
|
6
|
+
- **리뷰어:** @laco-dev
|
|
7
|
+
- **라인 코멘트:** 16
|
|
8
|
+
|
|
9
|
+
## 잘한 점 (설계 관점)
|
|
10
|
+
|
|
11
|
+
- **`Generator` 인터페이스 + FakeGenerator** — 전략 패턴 + 테스트 더블.
|
|
12
|
+
- **`Validator` 분리** — 검증 책임.
|
|
13
|
+
- **`RepeatInputProcess` 유틸 시도** — 입력 재시도 일반화.
|
|
14
|
+
|
|
15
|
+
## 못한 점 (설계 관점)
|
|
16
|
+
|
|
17
|
+
- **"스켈레톤 코드 작성" 커밋** — 구현 시작 전 비어있는 클래스만 만드는 커밋.
|
|
18
|
+
- **InputView 먼저 구현 → CarName 도메인 후행 구현으로 코드 두 번 수정**.
|
|
19
|
+
- **`RepeatInputProcess`가 `Any` 반환** — 타입 추론 무력화, 강제 캐스팅 필요.
|
|
20
|
+
- **Controller에 컬렉션 변환 한 줄에 많은 내용 압축** — 가독성 저하.
|
|
21
|
+
- **Validator와 Car init 양쪽 검증 → 학생이 자가 의문** ("이중 처리 필요한가?").
|
|
22
|
+
- **테스트 코드의 기댓값에 로직 작성** — 하드코딩이 더 명확.
|
|
23
|
+
- **Controller 단위 테스트 작성** — Controller는 UI 결합으로 단위 테스트 부적합, 통합 테스트가 맞음.
|
|
24
|
+
|
|
25
|
+
## 리뷰어 의견 요지
|
|
26
|
+
|
|
27
|
+
리뷰어 @laco-dev의 핵심 가르침:
|
|
28
|
+
|
|
29
|
+
1. **"커밋은 변화의 의미 단위"** — 스켈레톤 커밋은 그 의미가 작성자 본인만 안다. "귀찮음을 피하는 건 커밋이 아닌 다른 방법으로." 기능 단위 커밋.
|
|
30
|
+
|
|
31
|
+
2. **도메인 우선 구현** — InputView부터 짜면 도메인 모델이 나중에 만들어질 때 InputView를 *또* 수정. "도메인 로직을 먼저 구현해보면 어떨까?"
|
|
32
|
+
|
|
33
|
+
3. **검증의 위치 이동 = 의존성 제거** — Car init에 require 넣으면 Validator의 길이 검사 *불필요해짐*. "자동차 이름의 제약사항이 도메인 모델에 포함되었기 때문에 입력값에서 중복 검사할 필요 없음."
|
|
34
|
+
|
|
35
|
+
4. **Controller는 단위 테스트 X** — "UI나 콘솔과 같이 실행에 밀접한 관련이 있기 때문에 일반적으로 단위 테스트를 작성하지는 않음. 필요에 따라 전체 통합 테스트는 가능."
|
|
36
|
+
|
|
37
|
+
5. **함수 분리 = 가독성의 답** — 변수 분리만으로 안 풀리면 함수 분리. `finishGame = getMaxCount + findWinnersBy + printWinners` 3줄.
|
|
38
|
+
|
|
39
|
+
6. **`get*` vs `find*` 메서드 네이밍** — 코틀린 컬렉션 함수 의도에 맞게. `get` = 인덱스 접근, `find` = 조건 탐색.
|
|
40
|
+
|
|
41
|
+
- **대표 인용:**
|
|
42
|
+
> 가령, 자동차 이름을 입력받는 기능을 구현한 뒤 자동차 이름이라는 CarName 모델이 생기게 된다면, InputView의 구현이 따라서 변경이 되야 합니다. 즉 코드를 두번 이상 수정해야 한다는 의미가 될 수 있어요.
|
|
43
|
+
>
|
|
44
|
+
> — @laco-dev on `src/main/kotlin/view/InputView.kt`
|
|
45
|
+
|
|
46
|
+
> 자동차의 이름이 5글자 미만이어야 하는 것은 자동차의 역할일까요? Validator의 역할일까요? 예를 들어 다음 코드는 잘 동작을 할까요? `Car(name = "")`, `Car(name = "123456789")`
|
|
47
|
+
>
|
|
48
|
+
> — @laco-dev on `src/main/kotlin/exception/Validator.kt`
|
|
49
|
+
|
|
50
|
+
> 자동차의 이름에 대한 제약사항이 도메인 모델에 포함되었기 때문에 입력 값에서 중복으로 검사할 필요가 없어지게 된 것이 맞습니다! 즉 InputValidator에서 자동차 이름의 길이를 검사하는 것은 불필요해지게 되는 것입니다.
|
|
51
|
+
>
|
|
52
|
+
> — @laco-dev on `src/main/kotlin/exception/InputValidator.kt:13`
|
|
53
|
+
|
|
54
|
+
> 컨트롤러는 UI나 콘솔과 같이 실행에 밀접한 관련이 있기 때문에 일반적으로 단위 테스트를 작성하지는 않습니다. 필요에 따라서 전체 통합 테스트라고 부르는 동작을 할 수는 있습니다.
|
|
55
|
+
>
|
|
56
|
+
> — @laco-dev on `src/test/kotlin/controller/ControllerTest.kt:12`
|
|
57
|
+
|
|
58
|
+
## 얻은 교훈
|
|
59
|
+
|
|
60
|
+
- **도메인 우선 구현이 *재작업*을 줄인다**. InputView부터 짜면 도메인이 나중에 자리 잡을 때 입력 형식이 또 바뀜. 도메인 (CarName, Cars) 먼저 → View가 그 도메인에 맞춰 입력 받기.
|
|
61
|
+
- **도메인 invariant가 도메인 객체로 들어가면 외부 검증은 *사라진다*.** Car가 `require(name.length <= 5)`를 가지면 InputValidator의 같은 검증은 죽은 코드. *이중 검증을 유지하지 말고 한쪽을 지워라*.
|
|
62
|
+
- **Controller 단위 테스트의 함정.** Controller는 IO에 의존 → 단위 테스트가 의미 있는 경계가 아님. 정작 검증할 가치는 도메인. Controller는 통합 테스트의 자리.
|
|
63
|
+
- **테스트 기댓값에 로직을 쓰면 = 테스트가 또 하나의 구현.** `expected = car.position + 1` 같이 계산식 두면 같은 버그가 양쪽에 들어감. 하드코딩으로 *받은 그대로*.
|
|
64
|
+
- **`get*` vs `find*` 메서드 의도**. `get` = "있다고 확신, 인덱스 접근". `find` = "조건 탐색, 없을 수도".
|