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,52 @@
|
|
|
1
|
+
# PR #161 — [자동차 경주 - 리팩토링] 다온 미션 제출합니다
|
|
2
|
+
|
|
3
|
+
- **Reviewee:** [@moondev03](https://github.com/moondev03)
|
|
4
|
+
- **PR:** https://github.com/woowacourse/kotlin-racingcar/pull/161
|
|
5
|
+
- **단계:** 2단계 (리팩토링)
|
|
6
|
+
- **리뷰어:** @KwonDae
|
|
7
|
+
- **라인 코멘트:** 5
|
|
8
|
+
|
|
9
|
+
## 잘한 점 (설계 관점)
|
|
10
|
+
|
|
11
|
+
- **1단계 피드백 *후 자가 재검토*로 검증 위치 재조정** — "InputView 검증 → View-Model 결합도 ↑" 우려를 스스로 발견.
|
|
12
|
+
- **빈 문자열 같은 형식 검증은 InputView, 게임 규칙은 도메인**으로 명확한 책임 분리.
|
|
13
|
+
- **자기 의견을 PR에 명확히 표명 + 리뷰어 의견 요청**.
|
|
14
|
+
|
|
15
|
+
## 못한 점 (설계 관점)
|
|
16
|
+
|
|
17
|
+
- **Controller가 `RacingGame`을 내부 생성 (var)** — 외부 주입 안 함. 테스트 시 RacingGame 교체 불가.
|
|
18
|
+
- **`RacingGame`이 `lateinit var racingCars` 보유** — 게임 객체가 차량 리스트를 *나중에* 받음. 생성자에서 받는 게 자연스러움.
|
|
19
|
+
- **자동차 이름 중복 검증의 위치 토론에서 일급 컬렉션 미도입** — 학생이 도메인으로 옮겼지만, `Cars` 같은 일급 컬렉션이 아닌 List에서.
|
|
20
|
+
|
|
21
|
+
## 리뷰어 의견 요지
|
|
22
|
+
|
|
23
|
+
리뷰어 @KwonDae의 핵심 가르침:
|
|
24
|
+
|
|
25
|
+
1. **외부 주입의 이점** — Controller가 RacingGame을 내부에서 생성 vs 외부에서 받기. → 학생: "테스트 용이성 + Controller가 객체 생성 책임에서 분리." 깔끔히 답.
|
|
26
|
+
|
|
27
|
+
2. **lateinit 대신 생성자 주입** — RacingGame이 `lateinit var racingCars`로 차량을 나중에 받지 말고 생성자에서. → 학생: "특정 상태의 Car 리스트로 테스트 가능."
|
|
28
|
+
|
|
29
|
+
3. **검증 위치의 *재조정*** — 1단계에서 "View에 검증" 가이드를 따랐지만, 학생이 후속 미션에서 "View-Model 결합도 ↑" 우려로 재배치. 리뷰어 수용: "방향을 잘 캐치해주셔서 다행. 도메인 검증은 도메인에서, 입력값 검증은 InputView에서가 맞다."
|
|
30
|
+
|
|
31
|
+
4. **일급 컬렉션 예고** — "[자동차 이름들]이라는 게 어디서 검증해야 할까에 대해 고민이 많으셨던 것 같다. 이후 미션에서 '일급 컬렉션' 개념이 등장." → 다음 라운드 예고.
|
|
32
|
+
|
|
33
|
+
- **대표 인용:**
|
|
34
|
+
> [레이싱 게임은 두 대 이상이어야 한다], [자동차 이름 중복 검사] 같은 검증을 View에서 수행하면 View와 Model 간 결합도가 높아지는 문제가 발생하는 것 같습니다. 따라서 빈 문자열 입력 등 최소한의 입력값 검증은 InputView에서 수행하고, 게임 규칙과 관련된 검증은 해당 모델에서 수행하는 것이 적절하다고 판단했습니다.
|
|
35
|
+
>
|
|
36
|
+
> — @moondev03 (학생 자신) on `src/main/kotlin/racingcar/controller/RacingController.kt`
|
|
37
|
+
|
|
38
|
+
> 의도를 정확히 파악해주셨습니다. 위 검증 사항은 도메인에서 검증해도 충분하다고 생각하여 의견을 드렸습니다. 말씀주신 것 처럼 입력값에 대한 검증은 InputView에서, 도메인(자동차) 검증에 관한 검증은 도메인에서 이루어지는게 어떨가 싶어 제안드렸던 부분입니다
|
|
39
|
+
>
|
|
40
|
+
> — @KwonDae on `src/main/kotlin/racingcar/model/RacingGame.kt:16`
|
|
41
|
+
|
|
42
|
+
## 얻은 교훈
|
|
43
|
+
|
|
44
|
+
- **이전 라운드 피드백을 *맹목 흡수*하지 않고 *재검토*하는 능력**. "View에 검증 옮겨라"를 따랐지만 결합도가 올라가니 다시 조정. 가이드는 따라가되, *결과의 트레이드오프*를 자가 평가.
|
|
45
|
+
- **검증의 3분류**:
|
|
46
|
+
- **UI 형식** (빈 문자열, 숫자 아님) → View
|
|
47
|
+
- **도메인 규칙** (자동차 두 대 이상, 이름 중복) → Domain (이상적으론 일급 컬렉션)
|
|
48
|
+
- **시스템 무결성** (DB 제약 등) → Repository/외부 경계
|
|
49
|
+
- **외부 주입의 두 이점** — 테스트 용이성 + 객체 생성 책임 분리. Controller가 객체를 만들 때마다 그건 흙숟갈 의존성.
|
|
50
|
+
- **`lateinit var`는 거의 항상 "생성자 주입을 못 한 자리"**. 생성자에서 받을 수 있으면 받자.
|
|
51
|
+
- **리뷰어가 같은 답을 다른 방식으로 다시 던질 줄 안다.** 1단계에서 "View에 검증" 가이드의 *진짜 의도*는 "입력값 검증을 도메인에서 빼라"였고, 도메인 규칙 검증은 도메인에 남기는 게 맞음. 학생이 정확히 캐치.
|
|
52
|
+
- **일급 컬렉션은 컬렉션 자체에 도메인 규칙 (중복, 크기)을 부여하는 도구**. 그래서 다음 라운드에 등장.
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# PR #121 — [자동차 경주 구현] 오둥이 미션 제출합니다 (2단계 리뷰 회고)
|
|
2
|
+
|
|
3
|
+
- **Reviewee:** [@murjune](https://github.com/murjune)
|
|
4
|
+
- **PR:** https://github.com/woowacourse/kotlin-racingcar/pull/121
|
|
5
|
+
- **단계:** 2단계 (1단계 코드 리뷰 회고가 메인)
|
|
6
|
+
- **리뷰어:** @laco-dev
|
|
7
|
+
- **라인 코멘트:** 9
|
|
8
|
+
|
|
9
|
+
## 잘한 점 (설계 관점)
|
|
10
|
+
|
|
11
|
+
- **`RaceCars`에 책임을 자기 언어로 정의** — "RaceCar 집합 관리", "한 번에 움직임", "우승자 선정" 책임을 명확히 표명.
|
|
12
|
+
- **자기 의문(객체 equals 비교, ParameterizedTest 사용 등)을 깊이 정리** — 리뷰어와 핵심 토론을 이어감.
|
|
13
|
+
- **리뷰어의 메타 가이드를 흡수** — "맞다/틀리다가 아니라 적절한가"라는 메타 인식 획득.
|
|
14
|
+
|
|
15
|
+
## 못한 점 (설계 관점)
|
|
16
|
+
|
|
17
|
+
- **`comparePosition` 같은 비교 메서드의 정당화 부족** — 단순 Int 비교를 추상 메서드로 감싸는 것이 오버엔지니어링일 수 있음.
|
|
18
|
+
- **컨트롤러 테스트의 잘못된 단위** — 통합 테스트성 시나리오가 단위 테스트 자리에. 비즈니스 로직이 컨트롤러에 있으면 도메인 모델로 옮긴 후 단위 테스트.
|
|
19
|
+
- **테스트 클래스 패키지 불일치** — production 패키지와 다른 위치에 테스트 클래스.
|
|
20
|
+
- **객체 동등성 비교의 키 사용** — `model1.key == model2.key`처럼 키 비교로 가는 게 좋은지, equals 오버라이드인지 결정 필요.
|
|
21
|
+
|
|
22
|
+
## 리뷰어 의견 요지
|
|
23
|
+
|
|
24
|
+
리뷰어 @laco-dev는 이 라운드에서 **현실 세계 비유로 도메인 모델링** 을 짚었다. "자동차 이름/위치/엔진이 같아도 고유번호가 다른 자동차는 다른 자동차". 객체 동등성에 키를 활용하는 패턴이 도메인적으로도 옳을 수 있다는 가이드.
|
|
25
|
+
|
|
26
|
+
또한 **"맞다/틀리다 vs 적절한가"** 라는 메타 가이드: 같은 코드가 컨텍스트에 따라 답이 다르다는 점. `comparePosition`이 잘못된 것은 아니지만, 그것이 정말 필요한가의 판단이 더 중요.
|
|
27
|
+
|
|
28
|
+
ParameterizedTest 사용에 대한 학생의 거부와 리뷰어의 가이드 사이의 토론도 인상적 — "강요하지 않지만 이 라운드 이후로도 같은 가이드가 반복될 수 있음"이라는 균형 잡힌 표현.
|
|
29
|
+
|
|
30
|
+
- **대표 인용:**
|
|
31
|
+
> 자동차 고유번호는 유일합니다. 객체를 비교하는데 있어 지금과 같이 equals()를 직접 비교하기 어렵다면, 비교를 하기 위한 Key값을 사용하는 것이 더욱 효율적이다는 메시지를 전달하고 싶었습니다.
|
|
32
|
+
>
|
|
33
|
+
> — @laco-dev on `docs/racecar/Step_one_code_review_2.md`
|
|
34
|
+
|
|
35
|
+
> 명확하게 비교 가능한 Primitive 타입 대신 함수로 만드는 것은 오버 엔지니어링처럼 느껴집니다 ... 결론은 맞다 틀리다의 입장대신 적절한가? 를 답변으로 드릴 수 있겠습니다.
|
|
36
|
+
>
|
|
37
|
+
> — @laco-dev on `docs/racecar/Step_one_code_review_2.md` (comparePosition)
|
|
38
|
+
|
|
39
|
+
> 컨트롤러에 비즈니스 로직이 포함되어 있다면 그 로직을 도메인 모델로 옮기는게 올바른 순서입니다.
|
|
40
|
+
>
|
|
41
|
+
> — @laco-dev on `src/main/kotlin/racecar/controller/RaceCarGame.kt`
|
|
42
|
+
|
|
43
|
+
## 얻은 교훈
|
|
44
|
+
|
|
45
|
+
- **"맞다/틀리다"보다 "적절한가".** 같은 패턴(comparePosition 등)이 어떤 도메인엔 적절하고 어떤 도메인엔 오버엔지니어링이다. 컨텍스트 의존적 판단을 키우는 게 OOP 학습의 핵심.
|
|
46
|
+
- **도메인 모델링은 현실 세계 매핑에서 시작.** 자동차의 고유번호 = 키, 이름/위치/엔진 = 속성. 현실의 식별 방식을 코드로 옮기면 equals/hashCode의 자연스러운 키가 떠오른다.
|
|
47
|
+
- **컨트롤러 테스트는 단위 테스트가 어렵다.** 비즈니스 로직이 컨트롤러에 있다면 도메인으로 옮긴 뒤 단위 테스트. 컨트롤러는 통합 테스트 또는 mock 기반 테스트가 자연스러운 자리.
|
|
48
|
+
- **테스트의 패키지는 production의 거울.** 같은 패키지에 두면 "이 production 클래스의 테스트가 어디 있는가"를 한 번에 찾을 수 있음.
|
|
49
|
+
- **리뷰어의 균형 가이드** — "강요하지 않지만 이후로도 같은 코멘트가 반복될 수 있다"는 표현이 학생의 자율성을 보존하면서도 학습 방향을 안내. 본받을 만한 리뷰 스타일.
|
|
50
|
+
- **자기 결정의 회고로 이어지는 학습 사이클** — 학생이 "왜 그렇게 짰는지" 자기 언어로 적고, 리뷰어가 그 결정의 trade-off를 정리해주는 흐름이 가장 깊은 학습.
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# PR #95 — [자동차 경주 구현] 오둥이 미션 제출합니다
|
|
2
|
+
|
|
3
|
+
- **Reviewee:** [@murjune](https://github.com/murjune)
|
|
4
|
+
- **PR:** https://github.com/woowacourse/kotlin-racingcar/pull/95
|
|
5
|
+
- **단계:** 1단계
|
|
6
|
+
- **리뷰어:** @laco-dev
|
|
7
|
+
- **라인 코멘트:** 33
|
|
8
|
+
|
|
9
|
+
## 잘한 점 (설계 관점)
|
|
10
|
+
|
|
11
|
+
- **`RaceCars` 일급 컬렉션 도입** — 자동차 묶음을 별개 도메인 객체로.
|
|
12
|
+
- **자기 의문을 PR description에 풍부히 정리** — Car.name 가시성, View 싱글톤, format 위치 등.
|
|
13
|
+
- **테스트 가능성을 고민하며 input을 파라미터화 시도** — 단순 readln() 대신 주입 가능 구조.
|
|
14
|
+
|
|
15
|
+
## 못한 점 (설계 관점)
|
|
16
|
+
|
|
17
|
+
- **`Car.toString()` 오버라이드로 표현 책임 도메인 흡수** — 디자이너가 "표시 방법 변경"하면 도메인이 바뀜.
|
|
18
|
+
- **`Comparable` 구현으로 자동차 비교 가능** — "자동차 A가 자동차 B보다 크다"는 의미가 모호. 거리 비교라면 `compareByPosition` 같은 명시 메서드가 자연스러움.
|
|
19
|
+
- **`moveOrStop()`이 반환값을 가짐** — 자동차의 결정은 내부에. 외부가 그 결정을 받아 또 다른 처리를 하면 흐름이 외부에 노출.
|
|
20
|
+
- **`InputView`/`OutputView` 싱글톤 결정의 근거가 메모리 수거** — 진짜 기준은 "인스턴스화가 의미 있는가".
|
|
21
|
+
- **input 파라미터화로 테스트 가능성 확보 시도** — 호출자가 그 파라미터의 의미를 모름. 다른 표준 방법 권장.
|
|
22
|
+
- **린트 누락** — `gradlew ktlintCheck` 미실행으로 표준 컨벤션 어김.
|
|
23
|
+
- **자동차 이름 띄어쓰기 처리 누락** — `foo, bar, zoo` 입력 시 공백 그대로 표시.
|
|
24
|
+
- **InputView 위치가 자동차 경주 패키지 밖** — 모듈 응집도 누락.
|
|
25
|
+
|
|
26
|
+
## 리뷰어 의견 요지
|
|
27
|
+
|
|
28
|
+
리뷰어 @laco-dev는 **콘솔 vs 키오스크 비유** 로 UI 관심사 누수를 강력하게 짚었다. 출력 형식 변경이 Controller 수정인가 OutputView 수정인가? — UI 변경이 OutputView로 격리되어야 자연스러움. 같은 비유가 Car.toString()에도 적용 — 자동차 표시가 도메인의 일이 아님.
|
|
29
|
+
|
|
30
|
+
또한 **함수 이름 + 시그니처가 거짓말하면 안 된다**: `moveOrStop`이 반환값을 가지면 외부가 그 결정을 또 처리. 함수 이름의 후보 비교로 추상화 수준을 짚는 식.
|
|
31
|
+
|
|
32
|
+
`Comparable` 구현에 대해서는 **도메인 의미의 모호성** 을 짚음 — "자동차 A > 자동차 B"가 무엇을 의미하는지 사용자가 알기 어려움.
|
|
33
|
+
|
|
34
|
+
- **대표 인용:**
|
|
35
|
+
> 콘솔이 아닌 키오스크에 그림으로 출력을 하기로 결정했어요. 그렇다면 개발자는 컨트롤러를 수정해야 할까요? OutputView를 수정해야 할까요?
|
|
36
|
+
>
|
|
37
|
+
> — @laco-dev on `src/main/kotlin/OutputView.kt`
|
|
38
|
+
|
|
39
|
+
> 자동차 라는 개념만 두고 봤을 때 자동차 A가 자동차 B 보다 크다는 것은 무엇을 의미할까요? 지금은 경주를 하고 있기 때문에 단순히 거리값으로 비교를 할 수있습니다. 그런데 사실은 자동차 A가 더 무거우면 크다 였다면 어떻게 될까요?
|
|
40
|
+
>
|
|
41
|
+
> — @laco-dev on `src/main/kotlin/RaceCar.kt` (Comparable)
|
|
42
|
+
|
|
43
|
+
> `moveOrStop()` 함수가 반환값을 가지게 된 이유가 무엇일까요? 자동차가 전진하는 것은 스스로 판단하고 결정하게 됩니다.
|
|
44
|
+
>
|
|
45
|
+
> — @laco-dev on `src/test/kotlin/RaceCarTest.kt`
|
|
46
|
+
|
|
47
|
+
## 얻은 교훈
|
|
48
|
+
|
|
49
|
+
- **표시 형식의 변경은 UI 수정이어야 한다.** Controller나 도메인 객체의 `toString()`이 변경되어야 한다면 책임이 잘못 분배. 콘솔/키오스크/안드로이드 등 매체가 바뀌더라도 도메인은 안 흔들려야.
|
|
50
|
+
- **`Comparable`은 도메인 의미가 분명할 때만.** 도메인 객체에 자연스러운 순서가 있는 경우(`Money`, `Score` 등)에만 가치. 자동차처럼 다차원 객체는 명시적 메서드(`compareByPosition`)가 안전.
|
|
51
|
+
- **객체의 결정은 객체 안에서 끝낸다.** `moveOrStop()`이 boolean을 반환하면 그 결정이 외부로 새 나가서 또 처리됨. 자동차가 스스로 "이동했다/안 했다"를 알고 외부는 결과만 받음.
|
|
52
|
+
- **싱글톤 결정 기준 = 인스턴스화의 의미.** 메모리 수거가 아니라, "여러 인스턴스가 다른 상태를 가질 필요가 있는가?"가 진짜 질문.
|
|
53
|
+
- **린트는 코드 컨벤션의 기본기.** ktlintCheck/gradlew lint 같은 표준 도구가 잡아주는 일관성은 리뷰의 인지 부하를 크게 줄임.
|
|
54
|
+
- **테스트 가능성을 위한 파라미터화는 호출자 이해 가능성과 trade-off.** input을 파라미터로 받으면 테스트는 쉽지만 호출자가 의미를 모름. 표준 패턴(인터페이스 + fake) 사용.
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# PR #43 — [반달] 코틀린 자동차 경주 제출합니다
|
|
2
|
+
|
|
3
|
+
- **Reviewee:** [@no1msh](https://github.com/no1msh)
|
|
4
|
+
- **PR:** https://github.com/woowacourse/kotlin-racingcar/pull/43
|
|
5
|
+
- **단계:** 1단계
|
|
6
|
+
- **리뷰어:** @malibinYun
|
|
7
|
+
- **라인 코멘트:** 23
|
|
8
|
+
|
|
9
|
+
## 잘한 점 (설계 관점)
|
|
10
|
+
|
|
11
|
+
- **`Car` 자기 invariants 검증 (init)** — "이제 존재할 수 없는 Car 객체를 생성할 수 없게 되겠네요"라는 리뷰어 칭찬.
|
|
12
|
+
- **자기 결정의 회고적 응답** — Effective Kotlin 책까지 참고해 멤버변수/메서드 리턴 타입 명시의 장단점을 노션에 정리. 학습 사이클 깊음.
|
|
13
|
+
- **kotlin property 활용 (private set + public getter)** — Java 게터 패턴 탈피.
|
|
14
|
+
|
|
15
|
+
## 못한 점 (설계 관점)
|
|
16
|
+
|
|
17
|
+
- **`UserInputValidator`라는 별개 검증기** — 도메인 검증을 외부에. 응집도 손상.
|
|
18
|
+
- **Controller에서 직접 print** — View 책임이 새어 들어옴.
|
|
19
|
+
- **외부에서 Car의 숫자를 만들어 주입** — Tell-Don't-Ask 위반.
|
|
20
|
+
- **`RacingGame.cars`를 메서드로 초기화** — 생성자에서 받는 게 자연스러움.
|
|
21
|
+
- **maxBy로 가장 멀리 간 거리 계산** — 더 명확한 함수형 표현 가능.
|
|
22
|
+
- **`RandomNumber` 같은 list 사용** — 단일 숫자로 충분.
|
|
23
|
+
- **`NumberGenerator` 인터페이스와 `RandomNumberGenerator` 구현체의 이름 역전** — 추상이 짧고 구현이 긴 게 자연스러움.
|
|
24
|
+
- **테스트가 랜덤 범위(0~10)를 검증** — 의미 없음. 10만 번 돌아도 통과 가능성.
|
|
25
|
+
- **테스트 이름 추상화** — "랜덤 숫자가 4, 5가 나왔을 때 무엇이 일어나는지" 안 드러남.
|
|
26
|
+
|
|
27
|
+
## 리뷰어 의견 요지
|
|
28
|
+
|
|
29
|
+
리뷰어 @malibinYun는 **자기 학습 자료를 능동적으로 활용하라는 큰 가이드** — Effective Kotlin의 Item 4(Inferred Type), Item 14(변수 타입 명확화)를 직접 추천. 학생이 그 자료를 흡수해 노션에 정리한 회고가 인상적.
|
|
30
|
+
|
|
31
|
+
또한 **"객체에 메시지를 던져 자동차를 스스로 움직이게"** 라는 Tell-Don't-Ask 가이드와, **"검증은 필요한 곳에서 (응집도)"** 라는 위치 결정 원칙을 반복.
|
|
32
|
+
|
|
33
|
+
테스트에서 **"랜덤 범위 검증은 의미 없다"** — 0~10 잘못 적어도 10만 번 통과할 수 있다는 통계적 진리를 짧고 명확하게 전달.
|
|
34
|
+
|
|
35
|
+
- **대표 인용:**
|
|
36
|
+
> 숫자를 만드는 일을 외부에서 시키기보다, racingGame에게 메시지를 던져 자동차를 스스로 움직이게 해 보는 것은 어떨까요?
|
|
37
|
+
>
|
|
38
|
+
> — @malibinYun on `src/main/kotlin/racing/controller/RacingCarController.kt`
|
|
39
|
+
|
|
40
|
+
> 랜덤 값의 범위를 확인하는 것은 크게 의미가 없습니다. 사실 0~10로 잘못 적었지만, 10만 번을 실행해도 테스트가 통과되는 경우가 있을 수 있기 때문이에요.
|
|
41
|
+
>
|
|
42
|
+
> — @malibinYun on `src/test/kotlin/racing/model/RacingGameTest.kt`
|
|
43
|
+
|
|
44
|
+
> 검증은 필요한 곳에서 수행해서, 객체의 응집도를 높여주는 것은 어떨까요? 프로젝트가 커지면, 이후 관리가 어려워질 것이 우려되네요.
|
|
45
|
+
>
|
|
46
|
+
> — @malibinYun on `src/main/kotlin/racing/validators/UserInputValidator.kt`
|
|
47
|
+
|
|
48
|
+
## 얻은 교훈
|
|
49
|
+
|
|
50
|
+
- **자료 추천 → 학생 흡수 → 노션 정리 → 적용** 의 학습 사이클이 가장 깊은 학습을 만든다. Effective Kotlin Item 4/14를 참고하라는 가이드를 학생이 진지하게 흡수.
|
|
51
|
+
- **타입 명시는 미래 변경에 대한 자유.** Inferred 타입은 가장 좁은 구체 타입으로 추론되어, 슈퍼 클래스로 재할당이 안 되는 경우가 생긴다. 명시적 타입이 확장의 자유.
|
|
52
|
+
- **추상과 구현의 이름은 거꾸로** — 추상이 짧고 구현이 길어야 자연스럽다. `NumberGenerator`(추상) ← `RandomNumberGenerator`(구현)이 통상.
|
|
53
|
+
- **랜덤 자체 검증의 무의미.** 통계적 사건은 단위 테스트로 잡을 수 없음. 결정적 입력으로 결정적 동작을 검증.
|
|
54
|
+
- **응집도 = invariants의 주인이 그 invariants를 든다.** 외부 Validator는 invariants의 자리를 잃은 신호.
|
|
55
|
+
- **메서드 체이닝 학습.** `maxBy`, `foo`-prefix 함수들로 시퀀스를 명확히 표현. 학생이 그 다음 단계로 학습할 자료.
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# PR #69 — [반달] 2단계 자동차 경주 제출합니다
|
|
2
|
+
|
|
3
|
+
- **Reviewee:** [@no1msh](https://github.com/no1msh)
|
|
4
|
+
- **PR:** https://github.com/woowacourse/kotlin-racingcar/pull/69
|
|
5
|
+
- **단계:** 2단계
|
|
6
|
+
- **리뷰어:** @malibinYun
|
|
7
|
+
- **라인 코멘트:** 17
|
|
8
|
+
|
|
9
|
+
## 잘한 점 (설계 관점)
|
|
10
|
+
|
|
11
|
+
- **에러 메시지에 입력값 포함** — 리뷰어 칭찬 (디버깅 용이성).
|
|
12
|
+
- **Controller에서 멤버 변수 제거** — 리뷰어 칭찬.
|
|
13
|
+
- **`moveCars(cars: List<Car>): List<Car>` 시그니처로 테스트 가능성 확보** — 리뷰어 칭찬.
|
|
14
|
+
|
|
15
|
+
## 못한 점 (설계 관점)
|
|
16
|
+
|
|
17
|
+
- **`RacingGame`이 object + 내부 상태** — 한 게임당 새로 만들어야 하는 동시에 멀티스레드 환경 취약. object와 상태가 안 맞음.
|
|
18
|
+
- **`object`라 NumberGenerator 주입 불가** — 테스트 격리 한계.
|
|
19
|
+
- **Controller가 사이드 이펙트에 의존** — 흐름 추적이 어려움. 결과 반환 객체로 바꿔야.
|
|
20
|
+
- **`InputView`가 Car 생성** — 도메인 객체 생성 책임이 View로 새어 들어옴.
|
|
21
|
+
- **`moveCars`가 Car List 반환** — Car와 관련 없는 "움직임 정보" 객체가 더 자연스러움.
|
|
22
|
+
- **함수 체이닝이 한 줄에 다수** — 한 줄에 하나로 분리하면 가독성 향상.
|
|
23
|
+
- **테스트의 메시지 검증이 부분 일치(contains)** — 테스트가 거짓말할 수 있음.
|
|
24
|
+
- **검증문에 로직 포함** — 가독성 저하.
|
|
25
|
+
- **테스트가 도메인 로직(`getCars`)으로 데이터 빌드** — getCars 변경이 무관 테스트 깨뜨림.
|
|
26
|
+
- **NumberGenerator inner class 구현** — fun interface + lambda로 단순화 가능.
|
|
27
|
+
|
|
28
|
+
## 리뷰어 의견 요지
|
|
29
|
+
|
|
30
|
+
리뷰어 @malibinYun는 **상태 + object의 모순** 을 짚었다 — object는 싱글톤 + 영속, 상태가 있으면 멀티스레드 취약. 한 게임마다 새 인스턴스가 필요하면 class.
|
|
31
|
+
|
|
32
|
+
또한 **테스트 데이터 빌드 방식의 두 옵션**:
|
|
33
|
+
1. 도메인 로직(`getCars`)으로 빌드 → 그 로직 변경이 무관한 테스트 깨뜨림 (안 좋음)
|
|
34
|
+
2. 직접 하드코딩 → 테스트가 안정적
|
|
35
|
+
|
|
36
|
+
`InputView`가 Car를 만드는 것에 대해서는 **"이름 리스트만 넘기면 InputView의 일은 끝"** 이라는 명확한 책임 경계.
|
|
37
|
+
|
|
38
|
+
`fun interface` 학습 자료 + SAM 패턴 제시.
|
|
39
|
+
|
|
40
|
+
- **대표 인용:**
|
|
41
|
+
> 객체 내부에 상태 값이 존재하기 때문에 멀티쓰레드 환경에 취약한 형태예요. 상태 값을 가지지 않고, 필요한 값을 넘겨주면 결과를 반환하게끔 만들어보는 것은 어떨까요?
|
|
42
|
+
>
|
|
43
|
+
> — @malibinYun on `src/main/kotlin/racing/model/RacingGame.kt`
|
|
44
|
+
|
|
45
|
+
> 테스트에 필요한 Car를 도메인 로직을 통해 만들어 내는 것은 바람직하지 않아요. 승자에 대한 테스트인데, getCars가 이후 변경된다면 뜬금없는 이 테스트가 문제를 일으킬 수 있어요.
|
|
46
|
+
>
|
|
47
|
+
> — @malibinYun on `src/test/kotlin/racing/model/RacingGameTest.kt`
|
|
48
|
+
|
|
49
|
+
> View에서 도메인인 Car를 생성하는 건 어색해요. 입력 View에서는 사실, name List만 넘겨준다면 할 일을 모두 끝냈다고 생각해요.
|
|
50
|
+
>
|
|
51
|
+
> — @malibinYun on `src/main/kotlin/racing/view/InputView.kt:12`
|
|
52
|
+
|
|
53
|
+
## 얻은 교훈
|
|
54
|
+
|
|
55
|
+
- **object + 가변 상태는 안티패턴.** Object는 싱글톤이며 프로세스 동안 영속. 가변 상태가 있으면 멀티스레드/재실행 불가. object를 쓰려면 stateless 또는 thread-safe 보장.
|
|
56
|
+
- **테스트 데이터는 production 로직을 거치지 않는다.** `getCars()`로 데이터를 만들면 그 함수의 변경이 무관 테스트를 깨뜨림. 직접 하드코딩이 테스트 안정성.
|
|
57
|
+
- **View의 책임 경계 = 이름까지.** InputView가 도메인 객체(Car)를 만들면 도메인 생성 책임이 흩어진다. View는 raw 입력을 도메인이 받기 쉬운 형태(이름 리스트)로 전달.
|
|
58
|
+
- **`fun interface` + 람다 = SAM 패턴.** inner class로 inteface 구현하는 대신 fun interface 선언 후 `{ 1 }`처럼 람다로 넘김. 가독성 + 간결성.
|
|
59
|
+
- **함수 체이닝 한 줄 하나.** `cars.maxBy { ... }.position`보다 줄을 나누면 (1) 디버깅 쉬움, (2) 의도 단계가 보임, (3) 변경 시 영향 좁음.
|
|
60
|
+
- **에러 메시지에 입력값** = 디버깅 효율 + UX 동시 개선. 작은 변경의 큰 효과.
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# PR #48 — [수달] 자동차 경주 제출합니다
|
|
2
|
+
|
|
3
|
+
- **Reviewee:** [@otter66](https://github.com/otter66)
|
|
4
|
+
- **PR:** https://github.com/woowacourse/kotlin-racingcar/pull/48
|
|
5
|
+
- **단계:** 1단계
|
|
6
|
+
- **리뷰어:** @BeokBeok
|
|
7
|
+
- **라인 코멘트:** 19
|
|
8
|
+
|
|
9
|
+
## 잘한 점 (설계 관점)
|
|
10
|
+
|
|
11
|
+
- **생성자 의존성 주입** — 리뷰어 명시적 칭찬.
|
|
12
|
+
- **상수에 주석으로 의미 표현** — 의도 명시 시도 (다만 더 좋은 방법은 object 묶음).
|
|
13
|
+
- **자기 의문 적극 표명** — private 함수 테스트 방법, 검증 위치 등.
|
|
14
|
+
|
|
15
|
+
## 못한 점 (설계 관점)
|
|
16
|
+
|
|
17
|
+
- **`isMove`가 private + 내부에서 랜덤 생성** — 테스트 불가능. 파라미터로 받게 바꾸면 해결.
|
|
18
|
+
- **`BlankRemover` 유틸이 원본 데이터를 변경** — 사이드 이펙트. 새 데이터 반환이 안전.
|
|
19
|
+
- **`removeBlank` 같은 커스텀 함수가 시스템 함수(trim 등) 대체** — 가독성 저하.
|
|
20
|
+
- **`Strings.kt`에 상수 모음 + 주석** — object로 묶는 게 응집도 + 가독성에 더 좋음.
|
|
21
|
+
- **테스트 이름 모호** — "전체 기능", "노말 테스트" 등이 무엇을 검증하는지 안 드러남.
|
|
22
|
+
- **상수가 Controller에 — Input/Output 관련 상수가 View 자체로 가는 게 응집** — Controller 비대화 신호.
|
|
23
|
+
|
|
24
|
+
## 리뷰어 의견 요지
|
|
25
|
+
|
|
26
|
+
리뷰어 @BeokBeok는 **"private 함수의 테스트 = 책임 분리의 신호"** 라는 클래식 가이드를 매우 명확히 전달. 두 가지 해결책 제시:
|
|
27
|
+
1. 함수의 파라미터로 외부에서 값 주입 (랜덤성 격리)
|
|
28
|
+
2. 그 책임을 별개 public 클래스로 분리
|
|
29
|
+
|
|
30
|
+
또한 **"커스텀 함수 vs 시스템 함수"** — 시스템 함수가 더 가독성에 좋다는 가이드. 학생이 기능 분리에 집중하면서 본질을 놓친 사례.
|
|
31
|
+
|
|
32
|
+
**원본 데이터 변경 위험** — 사이드 이펙트가 다른 참조자에게 미치는 영향. 함수형 사고 (불변 + 새 데이터 반환)로 해결.
|
|
33
|
+
|
|
34
|
+
- **대표 인용:**
|
|
35
|
+
> isMove 함수가 테스트하기 어려운 이유는, 랜덤값을 함수 내부에서 생성하고 있기 때문입니다. 만약 값을 함수의 파라미터로 받게되면 어떨까요?
|
|
36
|
+
>
|
|
37
|
+
> — @BeokBeok on `src/main/kotlin/racingcar/service/RacingService.kt:22`
|
|
38
|
+
|
|
39
|
+
> private 함수를 테스트하기 위해서는, 외부에서도 접근이 가능하도록 public하게 만드는 것입니다. 내부에서만 접근하는데 public으로 만드는 것이 이상하게 느껴지신다면, 해당 로직을 클래스로 분리하면 됩니다.
|
|
40
|
+
>
|
|
41
|
+
> — @BeokBeok on `src/main/kotlin/racingcar/service/RacingService.kt:22`
|
|
42
|
+
|
|
43
|
+
> Controller는 View와 Domain에 접근이 가능하므로, 자칫 잘못하면 Controller가 커지게 됩니다.
|
|
44
|
+
>
|
|
45
|
+
> — @BeokBeok on `src/main/kotlin/racingcar/controller/ViewController.kt:59`
|
|
46
|
+
|
|
47
|
+
## 얻은 교훈
|
|
48
|
+
|
|
49
|
+
- **private 함수 테스트의 두 가지 답.** (1) 파라미터로 랜덤성 격리, (2) 별개 public 클래스로 분리. private을 그냥 풀어서 테스트하는 안티패턴은 회피.
|
|
50
|
+
- **커스텀 함수 vs 시스템 함수.** 표준 도구가 가능하면 커스텀 함수보다 시스템 함수가 가독성 + 유지보수에 좋음.
|
|
51
|
+
- **사이드 이펙트가 외부로 새면 위험.** 인자로 받은 데이터를 변경하면 호출자가 모르는 결과. 새 데이터 반환이 안전한 기본.
|
|
52
|
+
- **Controller의 상수는 도메인 위로 옮기는 후보.** Input 상수는 InputView로, Output 상수는 OutputView로 옮기면 Controller가 다이어트.
|
|
53
|
+
- **자기 의문이 명확한 답을 끌어낸다.** "private 함수 테스트 방법은?" 같은 질문이 리뷰어의 두 가지 답을 끌어냄. 질문 없이 코드만 받았다면 그 답이 안 왔을 수도.
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# PR #77 — [수달] 자동차 경주 step2 제출합니다
|
|
2
|
+
|
|
3
|
+
- **Reviewee:** [@otter66](https://github.com/otter66)
|
|
4
|
+
- **PR:** https://github.com/woowacourse/kotlin-racingcar/pull/77
|
|
5
|
+
- **단계:** 2단계
|
|
6
|
+
- **리뷰어:** @BeokBeok
|
|
7
|
+
- **라인 코멘트:** 14
|
|
8
|
+
|
|
9
|
+
## 잘한 점 (설계 관점)
|
|
10
|
+
|
|
11
|
+
- **InputController/OutputController 삭제** — 1단계의 "Controller가 다른 Controller를 제어" 어색함 정리.
|
|
12
|
+
- **원시값을 도메인 객체로 감싸 검증을 도메인으로** — 1단계의 Controller 검증을 도메인으로 이전.
|
|
13
|
+
- **테스트 이름에 "이상"/"이하"/"미만" 등 명세 단어 활용** — 가독성 향상.
|
|
14
|
+
- **`move()` 함수 통일** — 테스트용 별도 move 함수 제거, 하나로 통일.
|
|
15
|
+
|
|
16
|
+
## 못한 점 (설계 관점)
|
|
17
|
+
|
|
18
|
+
- **`InputController`/`OutputController` 잔재** — 다른 Controller를 제어하는 Controller라는 어색함. (리뷰 후 삭제됨)
|
|
19
|
+
- **`TryCount` 같은 명사구지만 -count 접미사** — `TryNumber`처럼 학생이 자기 회고로 더 적절한 명명에 도달.
|
|
20
|
+
- **상수가 클래스 외부 public** — Controller 내부에서만 쓰면 private.
|
|
21
|
+
- **테스트 이름이 일부 모호** — "노말" 등.
|
|
22
|
+
|
|
23
|
+
## 리뷰어 의견 요지
|
|
24
|
+
|
|
25
|
+
리뷰어 @BeokBeok는 **"Controller가 다른 Controller를 제어하는 패턴"** 의 어색함을 짚었다. Controller의 본질은 View와 Domain 연결이지 Controller 간 계층이 아님.
|
|
26
|
+
|
|
27
|
+
또한 **이름이 명사구여야 한다** 는 클래식 가이드. `TryCount` 같은 단어가 학생의 자기 회고 후 `TryNumber`로 진화.
|
|
28
|
+
|
|
29
|
+
테스트 이름의 명세화 — "이상/이하/미만"같은 도메인 단어로 비교 의도를 시그니처에 박는 가이드.
|
|
30
|
+
|
|
31
|
+
`move` 함수가 두 가지 (테스트용 + production용) 있는 패턴 — 다른 개발자가 어떤 걸 호출해야 하는지 혼란. 하나로 통일.
|
|
32
|
+
|
|
33
|
+
- **대표 인용:**
|
|
34
|
+
> InputController와 OutputController는 Controller의 성격에 맞지 않아보여요. 이렇게되면, Controller가 다른 Controller들을 제어하는 상황이 생기게 됩니다.
|
|
35
|
+
>
|
|
36
|
+
> — @BeokBeok on `src/main/kotlin/racingcar/controller/InputController.kt`
|
|
37
|
+
|
|
38
|
+
> "이상"과 "미만" 과 같은 단어를 활용해보면, 함수명만 보고도 로직을 이해하기가 편해져요.
|
|
39
|
+
>
|
|
40
|
+
> — @BeokBeok on `src/test/kotlin/racingcar/service/RacingServiceTest.kt`
|
|
41
|
+
|
|
42
|
+
> 아래 함수를 테스트하기 위해 만들어 놓은 함수로 보이네요. 다른 개발자의 입장에서 move함수를 호출할 때, 어떤 move함수를 호출해야할지 매번 선택의 순간이 올 것 같아요.
|
|
43
|
+
>
|
|
44
|
+
> — @BeokBeok on `src/main/kotlin/racingcar/model/Car.kt`
|
|
45
|
+
|
|
46
|
+
## 얻은 교훈
|
|
47
|
+
|
|
48
|
+
- **Controller 계층화의 위험.** Controller가 다른 Controller를 제어하면 그 계층의 시작이 어디인지, 끝이 어디인지 모호해진다. Controller는 단일 책임 (View ↔ Domain).
|
|
49
|
+
- **테스트 이름 = 시스템 명세.** "이상/이하/미만/초과" 같은 비교 단어가 함수명에 들어가면 그 자체가 명세. 외부 컨텍스트 없이 무엇이 어떤 조건에서 어떻게 동작하는지 보임.
|
|
50
|
+
- **테스트만을 위한 public 메서드 = 안티패턴.** `move()` 외에 `forceMove()` 같은 테스트 보조가 있으면 호출자가 어떤 걸 써야 할지 모름. 단일 public API.
|
|
51
|
+
- **이름의 진화** — TryCount → TryNumber. 학생이 자기 회고로 더 적절한 이름에 도달. 시간이 지나며 자기 이름의 어색함이 보이는 경험은 학습의 자연스러운 과정.
|
|
52
|
+
- **이전 라운드 리뷰의 광범위 흡수 = 학습 깊이.** 1단계의 InputController/OutputController 삭제, 도메인 검증 이전 등 큰 구조 변경. 다음 라운드에서 새로운 토론 시작 가능한 상태.
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# PR #152 — [자동차 경주 구현] 밀러 미션 제출합니다
|
|
2
|
+
|
|
3
|
+
- **Reviewee:** [@oungsi2000](https://github.com/oungsi2000)
|
|
4
|
+
- **PR:** https://github.com/woowacourse/kotlin-racingcar/pull/152
|
|
5
|
+
- **단계:** 1단계
|
|
6
|
+
- **리뷰어:** @lee-ji-hoon
|
|
7
|
+
- **라인 코멘트:** 31
|
|
8
|
+
|
|
9
|
+
## 잘한 점 (설계 관점)
|
|
10
|
+
|
|
11
|
+
- **trim 처리** — 입력 가공 신경 씀. 리뷰어 칭찬.
|
|
12
|
+
- **Regex 활용** — 정규 표현식으로 검증 정밀화.
|
|
13
|
+
- **자기 의문을 광범위하게 제기** — Configure 저장 방식, GlobalExceptionHandler 도입 등 메타 수준 토론.
|
|
14
|
+
- **예외 처리 설계 회고** — "지금은 필요 없다"는 결정에 도달한 추론 과정이 학습 가치 높음.
|
|
15
|
+
|
|
16
|
+
## 못한 점 (설계 관점)
|
|
17
|
+
|
|
18
|
+
- **`InputValidatorService`가 `List<Car>`를 반환** — Validator의 이름과 행위가 어긋남. 검증은 Car name만 다루는 게 응집.
|
|
19
|
+
- **검증을 함수로 너무 잘게 쪼갬** — `emptyCheck`, `positiveInputCheck` 등 호출자가 내부를 봐야 require가 있는지 알 수 있음. 시그니처에서 "예외 던질 수 있음"이 안 보임.
|
|
20
|
+
- **Regex가 생성 비용 비싼데 매 호출 생성** — invariant한 객체는 companion에서 한 번만.
|
|
21
|
+
- **`Car.distance`가 `var`** — 외부 setter 노출. private set 필요.
|
|
22
|
+
- **`Configure`로 설정값을 enum/object/companion 혼란** — 자기 기준 정립 진행 중.
|
|
23
|
+
- **`ApplicationTest`라는 거대 테스트 클래스** — 사실 Validator 검증인데 Application Test라는 명명 — 단위 테스트 그라데이션 깨짐.
|
|
24
|
+
- **`60~60.01%` 같은 확률 테스트** — 정상 동작 검증과는 다름. 의미 없는 확률 검사.
|
|
25
|
+
- **`Application`의 `mutableListOf<Car>()` 필드** — 라이프사이클 동안 살아있는 가변 상태.
|
|
26
|
+
- **`RaceService.race()`가 String 반환** — 그 String이 무엇인지 호출자가 본문을 봐야 앎.
|
|
27
|
+
|
|
28
|
+
## 리뷰어 의견 요지
|
|
29
|
+
|
|
30
|
+
리뷰어 @lee-ji-hoon는 **"이름과 시그니처가 약속을 거짓말하면 안 된다"** 를 일관되게 짚었다. `InputValidator`가 List<Car>를 반환하는 어색함, `getValidatedRaceCount`가 내부에서 require를 던지면서도 시그니처는 그것을 안 드러내는 점, `RaceService.race(): String`이 무엇의 String인지 모호한 점 — 모두 같은 본질.
|
|
31
|
+
|
|
32
|
+
또한 **테스트 단위의 적절성** — `ApplicationTest`가 사실 Validator 테스트라면 그 자체가 잘못된 단위. 테스트 단위가 책임 단위와 일치해야.
|
|
33
|
+
|
|
34
|
+
`GlobalExceptionHandler` 토론에서는 학생의 깊은 추론을 자연스럽게 끌어내며 "지금은 필요 없다"는 결정까지 도달하게 한 가이드도 인상적 — 답을 주지 않는 리뷰의 가치.
|
|
35
|
+
|
|
36
|
+
- **대표 인용:**
|
|
37
|
+
> `InputValidatorService` 의 역할은 Input의 Validate역할이라고 보여지는데요. 그 역할 관점으로 봤을 때 `List<Car>` 을 반환하는게 맞을까요?
|
|
38
|
+
>
|
|
39
|
+
> — @lee-ji-hoon on `src/main/kotlin/racingcar/InputValidatorService.kt`
|
|
40
|
+
|
|
41
|
+
> `emptyCheck` 내부를 들어가기 전까지는 `require` 인지 아닌지 알 수가 없기 때문이죠. 그렇기에 누군가 이 함수를 사용할 때 `getValidatedRaceCount` 만 보고 exception이 나는 것을 모르고 사용하게 될 수도 있습니다.
|
|
42
|
+
>
|
|
43
|
+
> — @lee-ji-hoon on `src/main/kotlin/racingcar/InputValidatorService.kt`
|
|
44
|
+
|
|
45
|
+
> race 라는 함수를 호출한뒤 String을 반환했을 때 이 String이 무엇인지 바로 알 수 있을까요?
|
|
46
|
+
>
|
|
47
|
+
> — @lee-ji-hoon on `src/main/kotlin/racingcar/RaceService.kt`
|
|
48
|
+
|
|
49
|
+
## 얻은 교훈
|
|
50
|
+
|
|
51
|
+
- **이름과 시그니처가 곧 함수의 계약.** `Validator`가 Car를 반환하면 약속이 깨진다. `getValidatedX(): X`로 의도가 시그니처에 박혀야 호출자가 안심.
|
|
52
|
+
- **검증 분해의 함정.** 한 검증 메서드를 여러 작은 메서드로 쪼개면 호출자가 "어디서 던지는지" 모호. 호출 시그니처 한 줄에서 `require`/`throws`가 보이도록 명시 또는 묶기.
|
|
53
|
+
- **invariant한 비용 객체는 한 번만 만든다.** Regex, 패턴, lookup 테이블 — 매 호출 생성은 보이지 않는 비용.
|
|
54
|
+
- **테스트 단위 = 책임 단위.** `ApplicationTest`가 사실 Validator 테스트라면, 그 책임을 들고 있는 자리(Validator)에 테스트가 살아야.
|
|
55
|
+
- **GlobalExceptionHandler 도입 여부는 도메인 결정.** "예외 종류가 많고, 다른 흐름을 만들고 싶다"가 진짜 동인. 지금은 단순 종료라면 도입은 과한 추상.
|
|
56
|
+
- **확률 테스트는 단위 테스트가 아니다.** "60% 확률"을 검증하려면 무한 반복이 필요. 결정적 입력으로 결과를 검증하는 게 단위 테스트의 정의.
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# PR #187 — [자동차 경주 2단계] 밀러 미션 제출합니다
|
|
2
|
+
|
|
3
|
+
- **Reviewee:** [@oungsi2000](https://github.com/oungsi2000)
|
|
4
|
+
- **PR:** https://github.com/woowacourse/kotlin-racingcar/pull/187
|
|
5
|
+
- **단계:** 2단계
|
|
6
|
+
- **리뷰어:** @lee-ji-hoon
|
|
7
|
+
- **라인 코멘트:** 13
|
|
8
|
+
|
|
9
|
+
## 잘한 점 (설계 관점)
|
|
10
|
+
|
|
11
|
+
- **`Car`에 비즈니스 로직(연료 4 이상 시 움직임) 잘 녹임** — 리뷰어 명시적 칭찬. "객체가 스스로 일을 한다"는 관점.
|
|
12
|
+
- **`GameResult` 도메인 객체 도입** — 결과를 일급으로.
|
|
13
|
+
- **`MoveTable`로 라운드별 이동 결과 모델링** — 도메인 어휘 풍부화.
|
|
14
|
+
- **자기 의문을 적극 표현** — view의 책임 범위, MoveTable의 private 생성자 등 토론 적극.
|
|
15
|
+
|
|
16
|
+
## 못한 점 (설계 관점)
|
|
17
|
+
|
|
18
|
+
- **`Controller`의 View import 누락** — 단순 실수지만 리뷰가 가지 못한 채 빌드 실패 상태.
|
|
19
|
+
- **`RaceService`에 사용 안 하는 Random 남음** — 죽은 의존이 남아 있음.
|
|
20
|
+
- **`Controller`의 private 함수가 테스트 필요** — 그 함수가 별개 책임의 신호.
|
|
21
|
+
- **`MoveTable`의 표시 로직이 도메인에 새어 들어옴** — UI 테스트 느낌의 단위가 도메인 테스트 칸에.
|
|
22
|
+
- **`GameResult`에 `\n` 줄바꿈 — UI 형식이 도메인에 침투** — Model이 View 형식을 알게 됨.
|
|
23
|
+
- **`View`가 입력 받고 Model을 직접 만듦** — view → model 의존이 가능하다는 것과, view가 model을 만들 자격이 있다는 것은 다름.
|
|
24
|
+
- **`MoveTable` 생성자가 public인 채로 두어 testability와 캡슐화 사이 trade-off** — 사용자(reviewee)도 자기 결정의 한계를 솔직히 언급.
|
|
25
|
+
|
|
26
|
+
## 리뷰어 의견 요지
|
|
27
|
+
|
|
28
|
+
리뷰어 @lee-ji-hoon는 이 라운드에서 **"의존 가능 ≠ 생성 권한"** 이라는 깊은 가이드를 짧은 비유로 전달. "View가 Car를 안다"는 것과 "View가 Car를 만든다"는 것은 다른 차원이라는 점. 현실 비유: 우리가 차를 안다고 직접 만들지 않고 어딘가에 요청한다.
|
|
29
|
+
|
|
30
|
+
또한 **"private 함수의 테스트 필요성은 책임 분리의 신호"** 라는 클래식한 가이드: private 함수가 테스트가 필요하면 그 함수는 사실 별개의 책임이며 다른 클래스에 있어야.
|
|
31
|
+
|
|
32
|
+
UI 관심사 누수에 대해서도 정확히 짚음 — `\n`이 GameResult 도메인에 있는 것은 잘못된 자리.
|
|
33
|
+
|
|
34
|
+
- **대표 인용:**
|
|
35
|
+
> 의존이 가능하다고 해서 그 객체를 생성할 역할이 부여가 되는 것은 아니니까요. ... 저희가 `Car` 를 알고 있다고 직접 생성하지는 않고 어딘가에 요청을 해서 받아오기도 하죠.
|
|
36
|
+
>
|
|
37
|
+
> — @lee-ji-hoon on `src/main/kotlin/racingcar/view/View.kt:19`
|
|
38
|
+
|
|
39
|
+
> private인 함수가 테스트가 필요해지는 순간 애초에 별도의 책임의 일부로서 원래는 다른 클래스에 들어있어야 했던 것이거나 테스트가 불필요한 상황이였을거 같아요!
|
|
40
|
+
>
|
|
41
|
+
> — @lee-ji-hoon on `src/main/kotlin/racingcar/Controller.kt:23`
|
|
42
|
+
|
|
43
|
+
> Domain Model이 UI의 관심사를 조금 갖고 간 느낌이 있는데요. MVC 관점에서 Model이 View에 표시될 데이터는 맞지만 `\n` 같은 줄 바꿈 로직은 View의 관심사이지 않을까 싶네요!
|
|
44
|
+
>
|
|
45
|
+
> — @lee-ji-hoon on `src/main/kotlin/racingcar/domain/GameResult.kt`
|
|
46
|
+
|
|
47
|
+
## 얻은 교훈
|
|
48
|
+
|
|
49
|
+
- **"의존 가능 ≠ 생성 권한".** View → Model 방향의 단방향 의존이 허용되더라도, View가 Model을 만드는 책임은 별개. 그 책임은 (보통) Controller나 Factory.
|
|
50
|
+
- **줄바꿈/포맷팅/색상 = 표시 형식 = View의 일.** GameResult가 `\n`을 만들면 도메인이 표시 매체에 결합된다. 표시 매체가 바뀌면 도메인이 바뀜.
|
|
51
|
+
- **private 함수의 테스트 욕구 = 책임 분리의 신호.** 그 함수가 진짜 필요한 검증이라면 별개 객체로 추출. 테스트하기 어렵다는 통증이 설계를 끌어당기는 가장 신뢰할 만한 신호.
|
|
52
|
+
- **죽은 코드는 의도를 흐린다.** 사용 안 하는 Random 의존, 미사용 import — 다 신호다. 호출자/유지보수자가 "이게 왜 있지?" 멈춤.
|
|
53
|
+
- **자기 한계 인정의 가치.** "저의 부족한 능력으로는 현재보다 더 직관적으로 구현 못함"이라는 솔직한 응답이 학습 사이클을 자연스럽게 만든다. 리뷰어도 그 솔직함 위에 다음 가이드를 더 정밀하게 줄 수 있다.
|
|
54
|
+
- **View가 입력 검증을 직접 해야 Controller가 신이 되지 않는다.** "할 일을 할 수 있는 자가 한다" — 책임의 자연스러운 위치 결정 원칙.
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# PR #143 — [자동차 경주 구현] 제이 미션 제출합니다
|
|
2
|
+
|
|
3
|
+
- **Reviewee:** [@parkjiminnnn](https://github.com/parkjiminnnn)
|
|
4
|
+
- **PR:** https://github.com/woowacourse/kotlin-racingcar/pull/143
|
|
5
|
+
- **단계:** 1단계
|
|
6
|
+
- **리뷰어:** @lee-ji-hoon
|
|
7
|
+
- **라인 코멘트:** 25
|
|
8
|
+
|
|
9
|
+
## 잘한 점 (설계 관점)
|
|
10
|
+
|
|
11
|
+
- **`Race` 도메인 객체 도입** — 도메인 모델링 의지.
|
|
12
|
+
- **확장 함수 활용 시도** — `carNames.duplicateCarNames()` 같은 메시지형 표현.
|
|
13
|
+
- **자기 결정에 대한 솔직한 회고** — object 사용 이유, 확장함수 선택 이유 등을 자기 언어로 표현.
|
|
14
|
+
|
|
15
|
+
## 못한 점 (설계 관점)
|
|
16
|
+
|
|
17
|
+
- **`RaceController`가 Input/Output 직접 수행** — Controller의 역할에 대한 정의가 흐림.
|
|
18
|
+
- **`playing` 함수가 `Pair<String, String>` 반환** — 호출자가 본문을 봐야 의미 추측.
|
|
19
|
+
- **공백/trailing comma 처리 누락** — "코니, 이지훈," 같은 입력에 무방비.
|
|
20
|
+
- **`ErrorHandler` 라는 광범위 이름** — 실제로는 validate 위주. 이름과 책임 어긋남.
|
|
21
|
+
- **`Constants.kt`로 상수 집중** — 결합도 안티패턴.
|
|
22
|
+
- **`Car`의 STOP count까지 추적** — 요구사항에 없는 데이터.
|
|
23
|
+
- **`GenerateRandomNumber` 동사 + 의도와 다른 책임** — 클래스명/함수명만 봐선 단순 난수 반환 예상.
|
|
24
|
+
- **`Race.isMove`로 validate 체크** — Race의 역할이 검증인가에 의문.
|
|
25
|
+
- **`moveOrStops`에서 Stop을 호출하지 않음** — 이름 거짓말.
|
|
26
|
+
- **모든 함수를 확장 함수로** — 확장 함수의 자리 기준이 흐림.
|
|
27
|
+
- **테스트 이름 추상** — "우승자리스트 테스트"가 무엇을 검증하는지 모름.
|
|
28
|
+
- **`ErrorHandlerTest` 클래스 역할 모호** — 무엇의 테스트인지 클래스명으로 안 드러남.
|
|
29
|
+
|
|
30
|
+
## 리뷰어 의견 요지
|
|
31
|
+
|
|
32
|
+
리뷰어 @lee-ji-hoon는 **"이름과 실제 동작의 일치"** 를 정밀하게 짚었다. `GenerateRandomNumber`, `moveOrStops`, `Race.isMove`, `ErrorHandler` 등 거의 모든 클래스/함수에서 이름과 행위의 어긋남을 찾아냄.
|
|
33
|
+
|
|
34
|
+
또한 **확장 함수 사용 기준** 을 명확히 제시 — `carNames.duplicateCarNames()` vs `duplicateCarNames(carNames)`의 비교로 "보통 어떤 경우에 확장함수를 쓰는가"를 학생이 스스로 결론에 도달하게 함.
|
|
35
|
+
|
|
36
|
+
object vs class 선택에 대한 학생의 답변("객체 생성 매번 지저분")에 대해 **"틀린 선택은 아니지만 명확한 이유로 쓰는가"** 라는 메타 질문 — "1) object를 어느 상황에서 선택하는가 명확히 알고, 2) object의 단점도 인지하는가"라는 두 단계 점검.
|
|
37
|
+
|
|
38
|
+
- **대표 인용:**
|
|
39
|
+
> Controller라는 네이밍을 갖고 있는 이상 계속 고민을 하게 될 것입니다. Controller니까 해도 되지 않을까?! 라는 생각을 갖게 되는거 같은데요.
|
|
40
|
+
>
|
|
41
|
+
> — @lee-ji-hoon on `src/main/kotlin/racingcar/controller/RaceController.kt`
|
|
42
|
+
|
|
43
|
+
> `playing`에서 `values`의 타입이 `Pair`인데 심지어 둘 다 String이라서 이 값이 무엇인지 저는 솔직히 `playing` 함수를 호출 하는 곳을 보기 전까지는 추측을 할 수 없었습니다.
|
|
44
|
+
>
|
|
45
|
+
> — @lee-ji-hoon on `src/main/kotlin/racingcar/controller/RaceController.kt`
|
|
46
|
+
|
|
47
|
+
> carNames.duplicateCarNames() vs duplicateCarNames(carNames) ... CarNames 중 중복이있는지 확인을 하고 중복인지 아닌지 Boolean 값을 반환한다. 라는 관점에서 어떤 것이 좀 더 명확하고 보통 확장함수를 구현 하는 경우가 어떤 경우인지 다시 생각해보면 좋겠습니다.
|
|
48
|
+
>
|
|
49
|
+
> — @lee-ji-hoon on `src/main/kotlin/racingcar/utils/ErrorHandler.kt`
|
|
50
|
+
|
|
51
|
+
## 얻은 교훈
|
|
52
|
+
|
|
53
|
+
- **이름은 실제 동작과 일치해야 한다.** `moveOrStops`가 stop을 호출하지 않으면 이름이 거짓말. 클래스/함수 이름과 본문이 일치하는지 항상 점검.
|
|
54
|
+
- **`Pair<String, String>` 같은 시그니처는 의도 누락의 신호.** 두 String이 무엇을 의미하는지 시그니처에서 안 보임. 도메인 객체 또는 의미 있는 이름의 data class로.
|
|
55
|
+
- **Controller라는 이름이 위험.** "Controller니까 무엇이든 해도 되지 않을까"라는 사고가 생긴다. 책임을 좁히려는 의식적 노력이 필요.
|
|
56
|
+
- **확장 함수의 자리.** "수신자가 그 메서드를 자기 메서드처럼 가졌으면 자연스러운가"가 기준. `carNames.checkDuplicates()`가 자연스러우면 확장함수, 그렇지 않으면 단순 함수.
|
|
57
|
+
- **object 선택의 두 가지 점검** — (1) 왜 object를 쓰는가 명확히 안다, (2) object의 단점(테스트 어려움, 싱글톤 상태 공유 등)을 인지한다. 둘 다 알고 쓰면 안전.
|
|
58
|
+
- **테스트 클래스도 클래스다.** `ErrorHandlerTest`라면 ErrorHandler의 테스트여야. 다른 검증을 거기에 두면 테스트 클래스의 책임이 흐려진다.
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# PR #158 — [자동차 경주 2단계] 제이 미션 제출합니다
|
|
2
|
+
|
|
3
|
+
- **Reviewee:** [@parkjiminnnn](https://github.com/parkjiminnnn)
|
|
4
|
+
- **PR:** https://github.com/woowacourse/kotlin-racingcar/pull/158
|
|
5
|
+
- **단계:** 2단계
|
|
6
|
+
- **리뷰어:** @lee-ji-hoon
|
|
7
|
+
- **라인 코멘트:** 15
|
|
8
|
+
|
|
9
|
+
## 잘한 점 (설계 관점)
|
|
10
|
+
|
|
11
|
+
- **확장 함수에서 일반 함수로 정리** — "함수명을 정할 때와 코드를 읽는 순간 일반 함수가 한눈에 이해하기 쉬움"이라는 자기 기준 정립.
|
|
12
|
+
- **`Race(cars, tryCount)` 생성자 도입** — "경기에 사용될 차량들"이 생성자로 들어가는 자연스러운 모델링. 리뷰어 칭찬.
|
|
13
|
+
- **View에 split 책임** — View가 자기 일을 한다는 분리. 리뷰어 칭찬.
|
|
14
|
+
- **View 주입 패턴** — Controller가 View를 주입받는 구조. 리뷰어 호기심 (`이유가 궁금하긴하네요`).
|
|
15
|
+
- **`CarNameValidator`로 도메인 검증 분리** — input의 검증을 도메인으로 옮긴 책임 배치.
|
|
16
|
+
- **테스트 함수명을 도메인 의도에 맞게** — 리뷰어 명시적 칭찬 💯.
|
|
17
|
+
|
|
18
|
+
## 못한 점 (설계 관점)
|
|
19
|
+
|
|
20
|
+
- **`Car.move(randomNumber)`로 외부에서 결정** — 이동 기준이 `4` 외에 `11~15`로 바뀌면 Car가 알 수 없는 구조. 외부 의존이 시그니처에 박힘.
|
|
21
|
+
- **`Race.cars`/`tryCount`를 외부에 노출** — 도메인 객체의 내부 상태가 public.
|
|
22
|
+
- **`Race.getPositions` 가 Race의 책임을 흐림** — Race가 View용 데이터를 만드는 일까지 함.
|
|
23
|
+
- **`InputValidator`가 `utils` 패키지에 위치** — utils 자체의 정체성이 흐림.
|
|
24
|
+
- **CarTest의 함수명 일부 추상** — "계산을 한다"는 무엇을 expect하는지 모름.
|
|
25
|
+
|
|
26
|
+
## 리뷰어 의견 요지
|
|
27
|
+
|
|
28
|
+
리뷰어 @lee-ji-hoon는 이 라운드에서 **"View는 멍청해야 한다"** 라는 명료한 가이드를 짚었다. View가 자기 일(`,` split 등)은 하되 그 이상의 결정은 못해야. 도메인이 View로 새지 않도록.
|
|
29
|
+
|
|
30
|
+
또한 **"Car가 그 결정 기준을 안다 vs 외부가 안다"** 라는 trade-off — 변화 가능성을 시뮬레이션해 책임 위치의 적절성을 진단. `Car.move(randomNumber)`로 외부 의존을 받는 구조 vs Car 자체가 `move()` 만 하는 구조.
|
|
31
|
+
|
|
32
|
+
학생의 적극적 자기 회고("일반함수가 한눈에 이해하기 쉬움")와 광범위 반영(InputValidator 위치 이동, Race 책임 조정)에 대해 명시적 칭찬과 다음 학습 가이드로 이어짐.
|
|
33
|
+
|
|
34
|
+
- **대표 인용:**
|
|
35
|
+
> 입력받은 randomNumber를 넘겨주고 있네요. 만약에 출전한 자동차의 move 기준이 11~15가 된다고 하면 어떻게 될까요?
|
|
36
|
+
>
|
|
37
|
+
> — @lee-ji-hoon on `src/main/kotlin/racingcar/domain/Car.kt:9`
|
|
38
|
+
|
|
39
|
+
> 항상 `View는 멍청해야 한다.` 라는 것을 기억을 해주시고 앞으로도 미션을 계속 진행해주시면 될거 같네요!
|
|
40
|
+
>
|
|
41
|
+
> — @lee-ji-hoon on `src/main/kotlin/racingcar/view/InputView.kt:7`
|
|
42
|
+
|
|
43
|
+
> 지금의 `Race`는 Domain Model 그 이상의 역할을 하고 있는 것 같아요. Controller와 Model 각 어느 역할을 어떻게 분배할지를 다시 고민해보면 좋을거 같습니다.
|
|
44
|
+
>
|
|
45
|
+
> — @lee-ji-hoon on `src/main/kotlin/racingcar/domain/Race.kt`
|
|
46
|
+
|
|
47
|
+
## 얻은 교훈
|
|
48
|
+
|
|
49
|
+
- **"View는 멍청해야 한다"는 디자인 원칙.** View가 자기 할 일은 하되(입력/출력) 도메인적 결정/계산까지 하면 그 결정이 View의 변경에 끌려간다. 콘솔/안드로이드/웹의 차이가 도메인을 흔들면 안 됨.
|
|
50
|
+
- **변화 가능성 시뮬레이션 = 책임 진단 도구.** "기준이 4에서 11~15로 바뀌면 Car가 알 수 있나?" 같은 질문은 책임 위치의 적절성을 즉시 보여줌. 책임은 변화에 닫혀 있어야.
|
|
51
|
+
- **확장 함수 사용의 자기 기준 정립.** 학생이 "함수명만 봐도 한눈에 이해되는가"를 기준으로 자기 결정 — 도구를 의식적으로 선택하는 학습.
|
|
52
|
+
- **이전 라운드 학습을 다음 라운드 결정에 일관 적용.** 1단계의 검증/View 책임 가이드를 2단계에서 `CarNameValidator` + View.split으로 분리해 일관성 확보. 학습이 연속됨.
|
|
53
|
+
- **명시적 칭찬의 가치.** "도메인적인 내용도 잘 녹아져있네요 💯" 같은 구체적 칭찬은 학생이 정확히 어떤 행동을 강화해야 하는지 명확히 알려줌. 단순 "good"보다 강력.
|
|
54
|
+
- **자기 기준의 표현이 학습의 정점.** "왜 확장함수에서 일반함수로 갔는가"를 학생이 자기 언어로 답한 순간이 학습의 최고점. 리뷰어는 그 답을 인정함으로써 학습을 확정.
|