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 #130 — [자동차 경주 리팩터링] 차람 미션 제출합니다
|
|
2
|
+
|
|
3
|
+
- **Reviewee:** [@aprilgom](https://github.com/aprilgom)
|
|
4
|
+
- **PR:** https://github.com/woowacourse/kotlin-racingcar/pull/130
|
|
5
|
+
- **단계:** 리팩터링
|
|
6
|
+
- **리뷰어:** @malibinYun
|
|
7
|
+
- **라인 코멘트:** 7
|
|
8
|
+
|
|
9
|
+
## 잘한 점 (설계 관점)
|
|
10
|
+
|
|
11
|
+
- **자기 의문의 깊이** — Controller 테스트 가능성에 대한 깊은 자기 회고를 PR description에 정리.
|
|
12
|
+
|
|
13
|
+
## 못한 점 (설계 관점)
|
|
14
|
+
|
|
15
|
+
- **`outputCarNamesRequest` vs `outputTrialCountRequest` 함수 본문 일관성 부족** — 한 쪽은 중괄호, 다른 쪽은 없음. 같은 책임의 함수는 같은 형태.
|
|
16
|
+
- **`RaceCar`의 위치 비교에 compareTo 사용** — `distance` 직접 비교가 더 단순.
|
|
17
|
+
- **`RaceCar`가 거리를 콘솔 형식으로 가공** — 도메인이 View 책임 가짐.
|
|
18
|
+
- **Controller가 라운드 진행 직접 수행** — 도메인 로직이 Controller에.
|
|
19
|
+
- **`WinnerCar`의 이름 모호** — "무엇의 max"가 시그니처에 안 드러남.
|
|
20
|
+
- **테스트 일부 주석 처리** — 1단계 리뷰의 오해로 테스트를 비활성화. 학생이 "equals & hashcode를 구현하지 말라"는 의미로 받아들임.
|
|
21
|
+
|
|
22
|
+
## 리뷰어 의견 요지
|
|
23
|
+
|
|
24
|
+
리뷰어 @malibinYun는 이 PR에서 인상적인 **자기 결정의 회복** 메시지를 전달:
|
|
25
|
+
|
|
26
|
+
학생이 1단계의 리뷰 때문에 테스트를 비활성화한 것에 대해 **"결코 틀렸다는 의미로 코멘트를 남겨놓은 게 아니었어요. 많은 생각과 고민을 하시고, 장단점을 비교해서 본인만의 선택을 하시길 바랐어요."** — 리뷰어 코멘트를 "지시"로 받아들이지 말고 "사고의 자극"으로 받아들이라는 메타 가이드.
|
|
27
|
+
|
|
28
|
+
Controller 테스트 가능성에 대해서는 **"많이 어려운 개념이니 넘어가도 좋다"** 는 학습 깊이 조절 가이드. 모든 코멘트가 즉시 반영해야 하는 것은 아니라는 점.
|
|
29
|
+
|
|
30
|
+
`멤버 변수` 가이드의 원래 의도를 재명시 — "객체 생성을 옮기라"가 아니라 "객체 자체가 상태를 갖지 않게 구성"이라는 점.
|
|
31
|
+
|
|
32
|
+
- **대표 인용:**
|
|
33
|
+
> 결코 틀렸다는 의미로 코멘트를 남겨놓은 게 아니었어요. 많은 생각과 고민을 하시고, 장단점을 비교해서 본인만의 선택을 하시길 바랐어요.
|
|
34
|
+
>
|
|
35
|
+
> — @malibinYun on `src/test/kotlin/RaceCarsTest.kt:1`
|
|
36
|
+
|
|
37
|
+
> 자동차를 원하는 라운드의 수 만큼 주행을 하게 만드는 것은 도메인 로직이에요! 이 도메인 로직을 분리해내는 게 이 미션에서 가장 핵심이 되겠네요.
|
|
38
|
+
>
|
|
39
|
+
> — @malibinYun on `src/main/kotlin/RaceCarGameController.kt:8`
|
|
40
|
+
|
|
41
|
+
> 자동차의 거리를 콘솔 뷰에 나타냘 수 있게 가공하는 것은 View의 역할이에요. 도메인에서 뷰 로직을 분리해보세요!
|
|
42
|
+
>
|
|
43
|
+
> — @malibinYun on `src/main/kotlin/RaceCar.kt:27`
|
|
44
|
+
|
|
45
|
+
## 얻은 교훈
|
|
46
|
+
|
|
47
|
+
- **리뷰어 코멘트 = 지시가 아닌 자극.** "이렇게 하라"가 아니라 "이렇게 생각해보라"는 의도. 학생이 그 자극을 받아 자기 결정에 도달하는 게 본질.
|
|
48
|
+
- **리뷰의 깊이는 학생의 학습 능력에 맞춘다.** Controller 테스트 같은 어려운 개념은 "이런 게 있구나" 수준으로 넘기는 것도 옳음. 모든 가이드를 즉시 반영해야 한다는 압박은 학습을 저해.
|
|
49
|
+
- **함수 형태의 일관성.** 같은 책임의 함수가 다른 본문 형태(중괄호 + 단일 표현식)면 호출자가 의도 차이를 추측해야. 일관성으로 인지 부하 감소.
|
|
50
|
+
- **거리 비교 = compareTo vs 직접 비교.** compareTo는 도메인 의미가 강할 때 가치. 단순 비교는 `==`, `>`로.
|
|
51
|
+
- **자기 결정의 회복** — 이전 리뷰가 "지시"로 받아들여진 흔적이 있으면, 리뷰어가 그것을 풀어줘야. 학생의 자율적 사고가 학습의 핵심.
|
|
52
|
+
- **이전 라운드의 가이드가 흡수되지 않으면 다시 강조** — Controller의 도메인 로직 분리는 1단계 → 리팩터링 라운드까지 반복. 핵심 학습이 누적되지 않으면 같은 자리에서 머문다.
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# PR #97 — [자동차 경주 구현] 차람 미션 제출합니다
|
|
2
|
+
|
|
3
|
+
- **Reviewee:** [@aprilgom](https://github.com/aprilgom)
|
|
4
|
+
- **PR:** https://github.com/woowacourse/kotlin-racingcar/pull/97
|
|
5
|
+
- **단계:** 1단계
|
|
6
|
+
- **리뷰어:** @malibinYun
|
|
7
|
+
- **라인 코멘트:** 26
|
|
8
|
+
|
|
9
|
+
## 잘한 점 (설계 관점)
|
|
10
|
+
|
|
11
|
+
- **`fun interface`로 NumberGenerator 격리** — 리뷰어 칭찬, 코틀린 문법 학습 의지.
|
|
12
|
+
- **자기 결정의 깊은 회고** — name 가시성, equals/hashcode 도입, 팩토리 메서드 선택의 자기 이유 표명.
|
|
13
|
+
- **`@JvmName` 어노테이션 + Type Erasure 학습** — JVM 시그니처 충돌 발견, 그것을 회피하기 위해 팩토리 선택.
|
|
14
|
+
|
|
15
|
+
## 못한 점 (설계 관점)
|
|
16
|
+
|
|
17
|
+
- **`RaceCar.moveOrStop` 반환값이 테스트 코드만을 위해 존재** — production 코드에서 미사용. 테스트 의미가 약함.
|
|
18
|
+
- **`RaceCars.equals/hashCode`가 테스트만을 위해 구현** — 학생 본인이 인지. 도메인적 필요가 아닌 테스트 우회.
|
|
19
|
+
- **`Controller`의 멤버 변수 활용** — 라이프사이클 1회 게임이라 함수 인자가 단순.
|
|
20
|
+
- **테스트가 `@ParameterizedTest` 미활용** — 같은 형태 케이스를 데이터로.
|
|
21
|
+
- **`Cars` 초기 위치를 주입할 수 없는 구조** — 결정적 시나리오 빌드 어려움.
|
|
22
|
+
|
|
23
|
+
## 리뷰어 의견 요지
|
|
24
|
+
|
|
25
|
+
리뷰어 @malibinYun는 학생의 매우 깊은 자기 회고에 대해 **두 가지 메타 가이드** 를 전달:
|
|
26
|
+
|
|
27
|
+
1. **"학식 앱 크롤러 vs 학교 페이지 리뉴얼"** 비유로 책임의 상대성 — 정답이 없는 상황에서 누가 책임을 가져야 하는지의 비유. 권한과 영향력에 따라 책임의 위치가 바뀜.
|
|
28
|
+
|
|
29
|
+
2. **"결정한 이유의 trade-off 정리"** — 옳고 그름이 아니라 "본인이 이 결정을 내린 이유"가 가장 중요. 무엇을 포기하고 무엇을 취했나? 다른 길이었다면 어땠을까?
|
|
30
|
+
|
|
31
|
+
테스트 코드만을 위한 production 코드(`equals/hashCode`, `moveOrStop` 반환값)에 대해 **"테스트 코드만을 위해 만들어진 기능으로 테스트하면 정말로 코드 동작을 검증한 것인가?"** 라는 본질 질문.
|
|
32
|
+
|
|
33
|
+
- **대표 인용:**
|
|
34
|
+
> 프로덕션 코드에서 사용하지 않는, 테스트 코드만을 위해 만들어진 기능으로 테스트를 작성한다면, 그것은 정말로 코드 동작을 검증했다고 볼 수 있을까요?
|
|
35
|
+
>
|
|
36
|
+
> — @malibinYun on `src/main/kotlin/RaceCar.kt`
|
|
37
|
+
|
|
38
|
+
> 답이 없어서 답답하실 것 같아요. 하지만 그만큼 개발의 세계에는 정답이 존재하지 않아요. ... 옮고 그럼을 떠나서, 본인이 해당 결정을 내린 이유가 가장 중요해요. 결정한 이유에는 어떤 장단점이 있었고, 무엇을 포기해서 무엇을 취했으며, 어떤 결과를 얻으셨나요?
|
|
39
|
+
>
|
|
40
|
+
> — @malibinYun on `src/main/kotlin/RaceCar.kt:2`
|
|
41
|
+
|
|
42
|
+
## 얻은 교훈
|
|
43
|
+
|
|
44
|
+
- **테스트 코드만을 위한 production = 거짓 검증.** 테스트가 production 동작을 검증해야 의미. production에서 안 쓰는 함수를 테스트하면 그건 테스트의 동어반복.
|
|
45
|
+
- **`equals/hashCode`의 도메인적 정당화.** 도메인이 객체 동등성을 정의할 이유가 있어야 구현. 단지 테스트 비교를 위해서라면 다른 방법(데이터 단위 비교) 필요.
|
|
46
|
+
- **결정의 이유가 옳고 그름보다 중요.** "이걸 선택한 이유 + 다른 길의 trade-off" 정리 능력이 OOP 학습의 정점. 학생이 도달한 자기 회고가 그 능력의 증거.
|
|
47
|
+
- **현실 비유로 책임 상대성 표현.** "학식 앱 vs 학교 페이지" 비유는 책임의 위치가 권한/영향력에 따라 바뀐다는 통찰. 단순 "누가 해야 한다"가 아님.
|
|
48
|
+
- **Type Erasure 학습이 만들어낸 디자인 결정.** 학생이 JVM 동작을 학습하면서 팩토리 메서드라는 선택에 도달. 언어 + 플랫폼 이해가 디자인 결정에 직결.
|
|
49
|
+
- **`name`을 private으로 막을지 vs 노출할지의 trade-off.** 외부에서 알아야 한다면 막을 수 없음. 의도치 않은 사용을 막는 게 본질이라면 다른 보호(타입, 인터페이스) 필요.
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# PR #23 — [자동차 경주] 어썸오 미션 제출합니다
|
|
2
|
+
|
|
3
|
+
- **Reviewee:** [@awesomeo184](https://github.com/awesomeo184)
|
|
4
|
+
- **PR:** https://github.com/woowacourse/kotlin-racingcar/pull/23
|
|
5
|
+
- **단계:** 2단계 (단일 PR)
|
|
6
|
+
- **리뷰어:** @summerlunaa, @hyewoncc (페어 리뷰)
|
|
7
|
+
- **라인 코멘트:** 10
|
|
8
|
+
|
|
9
|
+
## 잘한 점 (설계 관점)
|
|
10
|
+
|
|
11
|
+
- **Car에 `private set`**, companion object 위치 컨벤션.
|
|
12
|
+
- **`count.value` 같은 value 객체 활용** (Count 같은 도메인 타입).
|
|
13
|
+
- **`for (i in 1..n)` 외에도 `tailrec` 같은 코틀린 idiom 시도**.
|
|
14
|
+
|
|
15
|
+
## 못한 점 (설계 관점)
|
|
16
|
+
|
|
17
|
+
- **OutputView에서 `+` 문자열 연결 (postfix 활용 가능)**.
|
|
18
|
+
- **`x` 같은 일반 변수명** — 의미 모름.
|
|
19
|
+
- **`for` loop instead of `repeat`**.
|
|
20
|
+
- **`tailrec`이 try문 내부에는 적용 안 됨** — 학생이 적용 후 발견.
|
|
21
|
+
|
|
22
|
+
## 리뷰어 의견 요지
|
|
23
|
+
|
|
24
|
+
페어 리뷰어 @summerlunaa, @hyewoncc의 메시지:
|
|
25
|
+
|
|
26
|
+
1. **`joinToString(separator, postfix)` 활용** — 문자열 연결 한 줄로.
|
|
27
|
+
|
|
28
|
+
2. **`repeat`** — for문보다 의도 명시적.
|
|
29
|
+
|
|
30
|
+
3. **`tailrec` 꼬리재귀** — 코틀린 idiom. 단, try-catch 안에서는 적용 안 됨.
|
|
31
|
+
|
|
32
|
+
4. **`++` 대안 = `position++`** — 학생이 `x` 같은 변수명 회피.
|
|
33
|
+
|
|
34
|
+
- **대표 인용:**
|
|
35
|
+
> 코틀린은 꼬리재귀를 문법적으로 지원하는군요! 그런데 적용해보니까 try문에서는 tailrec이 적용이 안된다고 경고문구가 뜨네요. 꼬리재귀를 적용할 수 있는 구조인지는 조금 더 고민을 해봐야될 것 같아요!
|
|
36
|
+
>
|
|
37
|
+
> — @awesomeo184 (학생) on `src/main/kotlin/racingcar/RacingGame.kt`
|
|
38
|
+
|
|
39
|
+
> 코틀린은 한 기능에도 정말 많은 키워드가 있는 것 같아요, 익숙한 걸 쓰기 전에 더 찾아봐야겠습니다
|
|
40
|
+
>
|
|
41
|
+
> — @hyewoncc on `src/main/kotlin/racingcar/RacingGame.kt`
|
|
42
|
+
|
|
43
|
+
## 얻은 교훈
|
|
44
|
+
|
|
45
|
+
- **`joinToString`의 prefix/postfix/separator** = 문자열 연결의 거의 모든 케이스 해결. `+` 연산자 + println 대신 한 줄.
|
|
46
|
+
- **`tailrec`의 제약 = try-catch 안에서 안 됨**. 컴파일러가 꼬리 위치 보장 못 함. 재귀가 정말 꼬리 위치인지 확인.
|
|
47
|
+
- **변수명 = 의미가 보이는 이름**. `x`, `i` 같은 짧은 이름은 의미 0. `index`, `count`, `position` 등.
|
|
48
|
+
- **페어 리뷰의 가치 = 협력적 학습**. 학생이 새로운 idiom 발견 (`tailrec`), 다른 리뷰어도 함께 배움. 학습이 순환적.
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# PR #35 — [우기] 코틀린 자동차 경주 제출합니다
|
|
2
|
+
|
|
3
|
+
- **Reviewee:** [@boogi-woogi](https://github.com/boogi-woogi)
|
|
4
|
+
- **PR:** https://github.com/woowacourse/kotlin-racingcar/pull/35
|
|
5
|
+
- **단계:** 1단계
|
|
6
|
+
- **리뷰어:** @woowajames
|
|
7
|
+
- **라인 코멘트:** 30
|
|
8
|
+
|
|
9
|
+
## 잘한 점 (설계 관점)
|
|
10
|
+
|
|
11
|
+
- **`NumberGenerator` 인터페이스 도입 시도** — 무작위 의존 격리.
|
|
12
|
+
- **데이터 클래스 활용** — `CarPath`처럼 도메인 데이터를 명시적 객체로.
|
|
13
|
+
- **다양한 케이스 테스트** — 여러 시나리오를 ParameterizedTest 등으로.
|
|
14
|
+
- **for 대신 repeat 활용** — 코틀린 표준 도구 사용.
|
|
15
|
+
|
|
16
|
+
## 못한 점 (설계 관점)
|
|
17
|
+
|
|
18
|
+
- **`util/Constants.kt`, `util/Extension.kt` — util 안티패턴 집약** — 결합도 증가의 가장 큰 원인. 사용처가 모두 util에 의존.
|
|
19
|
+
- **`InputView.bufferedReader/Writer` 공유** — 성능 최적화 의도지만 단순 readLine() 수준에서 필요 없음. 단순함 우선.
|
|
20
|
+
- **`Application`에서 단순 `startGame()`만 호출하는데 별도 Controller** — Controller가 단순 호출자라면 그 자체가 필요한가.
|
|
21
|
+
- **`CarRacingGameController`가 도메인 패키지 내부** — Controller는 도메인 밖이라는 MVC 분리 누락.
|
|
22
|
+
- **이름 split, 검증, Cars 생성이 한 메서드에** — 단일 책임 위반.
|
|
23
|
+
- **검증 후 별도 변환 — 검증과 변환 분리되지 않음** — 검증을 통과한 시점에 이미 원하는 타입으로 반환하는 편이 자연스러움.
|
|
24
|
+
- **View용 로직(횟수만큼 출력)이 Controller에** — View 책임 누수.
|
|
25
|
+
- **`NumberGenerator` 인터페이스가 테스트만을 위해 존재** — 진짜 추상 가치가 없는 추상.
|
|
26
|
+
- **`CarMovingTest`처럼 별도 fake 클래스로만 테스트 가능** — 테스트 더블 클래스를 굳이 만드는 대신 메서드 주입으로 충분.
|
|
27
|
+
- **`CarRacingGame`의 우승자 선정 로직 테스트 누락** — 가장 중요한 도메인 검증이 없음.
|
|
28
|
+
- **`InputError` 같은 클래스의 위치** — 입력 관련은 입력 책임자 곁.
|
|
29
|
+
- **상수가 한 곳에서 다른 곳으로 옮겨갔지만 여전히 다른 클래스에 의존** — Constants 분해의 본질을 놓침. "분해 + 자기 곁에" 이어야.
|
|
30
|
+
- **`WinnerTest`, `CarMovingTest`처럼 클래스명-Test 규칙 위반** — 별도 테스트 클래스가 분리됐다는 것은 production 클래스가 두 가지 역할.
|
|
31
|
+
- **`object OutputView`가 편의를 위해 사용** — 가시성 통제 누락.
|
|
32
|
+
- **`All` 같은 모호한 식별자** — 도메인 어휘 부재.
|
|
33
|
+
|
|
34
|
+
## 리뷰어 의견 요지
|
|
35
|
+
|
|
36
|
+
리뷰어 @woowajames는 매우 강하게 **"util 안티패턴"** 과 **"결합도 = 변경의 비용"** 을 짚었다. Util 클래스/Constants 분해의 진짜 의미는 "단일 개념 = 단일 클래스"이지, 단지 파일을 나누는 게 아님을 명확히 표현.
|
|
37
|
+
|
|
38
|
+
또한 **테스트 클래스의 분리가 production 클래스의 책임 분리를 폭로** 한다는 강력한 관찰: `WinnerTest`/`CarMovingTest`라는 별도 클래스가 필요한 시점에 `CarRacingGame`은 이미 두 가지 책임을 가짐.
|
|
39
|
+
|
|
40
|
+
테스트 더블 측면에서는 **메서드 주입의 단순함** — 별도 fake 클래스를 만들기 전에 "메서드 파라미터로 결과 받기"가 우선.
|
|
41
|
+
|
|
42
|
+
- **대표 인용:**
|
|
43
|
+
> 단일 개념이 단일 클래스에 포함되면 그 개념과 관련된 요구 사항을 수정할 때 해당 클래스만 수정하면 되니까 효율적이겠죠?
|
|
44
|
+
>
|
|
45
|
+
> — @woowajames on `src/main/kotlin/util/Constants.kt`
|
|
46
|
+
|
|
47
|
+
> 보통 테스트할 클래스명Test로 하는데 이렇게 CarRacingGame에 있는 기능을 테스트 하기 위해서 테스트 클래스가 분리된다는 것은 CarRacingGame도 두 가지 이상의 역할을 하고 있는게 아닐까요?
|
|
48
|
+
>
|
|
49
|
+
> — @woowajames on `src/test/kotlin/WinnerTest.kt`
|
|
50
|
+
|
|
51
|
+
> Constants 클래스를 다른 여러 클래스로 나눈 것일 뿐 결국 근본적인 문제는 똑같이 발생하고 있네요.
|
|
52
|
+
>
|
|
53
|
+
> — @woowajames on `src/main/kotlin/data/Car.kt:21`
|
|
54
|
+
|
|
55
|
+
## 얻은 교훈
|
|
56
|
+
|
|
57
|
+
- **결합도는 "변경 비용의 크기"다.** Util/Constants가 결합도 핵심인 이유는 그 한 파일 변경이 전체에 파동을 일으키기 때문. "단일 개념이 단일 클래스에"가 결합도를 낮추는 가장 직접적 원칙.
|
|
58
|
+
- **상수 분해의 본질 = "그 도메인의 주인 곁에".** Constants를 N개 파일로 쪼개도, 각 파일이 여전히 다른 클래스의 상수를 알면 결합도는 안 줄어든다. 자기 도메인에 흡수.
|
|
59
|
+
- **테스트 클래스 분리 패턴은 책임 분리의 거울.** `XxxTest`, `XxxMovingTest`, `XxxWinnerTest` 같은 다중 테스트 클래스는 production 클래스의 책임 다중성을 알린다.
|
|
60
|
+
- **테스트 더블의 단순함 단계:** (1) 메서드 인자로 결과 주입 → (2) 인터페이스 + fake → (3) mock 라이브러리. 1번으로 충분하면 2/3은 오버.
|
|
61
|
+
- **추상화는 "다른 구현이 정말 존재할 때" 가치.** 테스트만을 위한 인터페이스는 추상의 가치가 약하다 — 그 자체로 결합도를 만든다.
|
|
62
|
+
- **단일 책임 원칙의 신호:** (1) 함수 안에 여러 동사, (2) 별도 테스트 클래스 분리, (3) 같은 클래스를 여러 곳에서 다른 부분만 사용. 셋 다 책임 분리의 단서.
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# PR #59 — [우기] 2단계 자동차 경주 제출합니다
|
|
2
|
+
|
|
3
|
+
- **Reviewee:** [@boogi-woogi](https://github.com/boogi-woogi)
|
|
4
|
+
- **PR:** https://github.com/woowacourse/kotlin-racingcar/pull/59
|
|
5
|
+
- **단계:** 2단계
|
|
6
|
+
- **리뷰어:** @woowajames
|
|
7
|
+
- **라인 코멘트:** 17
|
|
8
|
+
|
|
9
|
+
## 잘한 점 (설계 관점)
|
|
10
|
+
|
|
11
|
+
- **`CarGenerator` 분리로 Car 생성 책임 격리** — 1단계의 비대 Controller에서 떼냄.
|
|
12
|
+
- **try-catch 패턴 정리** — 1단계의 부적절한 try-catch를 명시적으로 다른 형태로 변경.
|
|
13
|
+
- **검증 책임을 별도 클래스로 분리** — `ValidateNumberOfTry` 등.
|
|
14
|
+
- **`OutputView`의 출력 패턴 개선** — 리뷰어가 명시적으로 "이 방법 너무 좋네요" 칭찬.
|
|
15
|
+
|
|
16
|
+
## 못한 점 (설계 관점)
|
|
17
|
+
|
|
18
|
+
- **`ValidateUseCases`라는 data class로 검증기들을 묶음** — "두 검증이 관련 있다"는 이유로 묶었지만, 사실 별개 책임. data class가 단순 컨테이너로 쓰이는 부적절한 사용.
|
|
19
|
+
- **검증 클래스 이름이 동사형** (`ValidateNumberOfTry`) — 명사형(`NumberOfTryValidator`)이 객체 모델링에 더 맞음.
|
|
20
|
+
- **`model` 패키지 분리, Car를 도메인 아닌 모델로** — model/domain/domain model의 차이를 모호하게 인식한 흔적.
|
|
21
|
+
- **`Referee` 도입했지만 `Winner`보다 와닿지 않음** — reviewer 개인 선호이지만, 도메인 어휘로는 `Winner`가 더 직관.
|
|
22
|
+
- **`RefereeTest`라는 명명** — 테스트 클래스명은 production 클래스명 + Test가 표준.
|
|
23
|
+
- **`GameBaseTest`라는 추상 부모** — 공통 상속 자체는 좋지만, 테스트 케이스의 유연성을 해칠 수 있음 (예: 전진 임계값 5로 바꿔 테스트하기 어려운지).
|
|
24
|
+
- **테스트가 `domainTest/` 같은 패키지에 Controller 테스트도 포함** — 패키지 분류 불일치.
|
|
25
|
+
- **`GameBaseTest`라는 헬퍼가 일반 테스트 클래스와 같은 위치** — 헬퍼인지 테스트인지 이름만 보고 모름.
|
|
26
|
+
|
|
27
|
+
## 리뷰어 의견 요지
|
|
28
|
+
|
|
29
|
+
리뷰어 @woowajames는 **"data class의 적절한 사용"** 을 짚었다 — 단순히 "관련 있다"는 이유로 다른 책임의 두 객체를 data class로 묶는 것은 잘못된 추상화. 별개 책임이면 별개 클래스로 두는 게 자연스럽다.
|
|
30
|
+
|
|
31
|
+
또한 **테스트 부모 클래스의 trade-off** — 공통화는 재사용을 늘리지만 케이스의 유연성을 해친다. "5라는 값으로 변경해서 테스트하려면 쉽게 가능한가?"라는 질문이 그 trade-off의 본질.
|
|
32
|
+
|
|
33
|
+
테스트 클래스 이름과 위치는 한 명확한 약속이 있어야 함 — `production 클래스명 + Test`, 패키지 분리는 production의 거울.
|
|
34
|
+
|
|
35
|
+
- **대표 인용:**
|
|
36
|
+
> 이러한 형태의 data class가 어떤 장점이 있을까요? class가 아닌 data class를 사용하면서 어떠한 효과를 얻고자 하셨는지 궁금합니다.
|
|
37
|
+
>
|
|
38
|
+
> — @woowajames on `src/main/kotlin/domain/validator/ValidateUseCases.kt`
|
|
39
|
+
|
|
40
|
+
> 5라는 값일 때도 정상적으로 동작하는지 확인하려면 현 상황에서 쉽게 변경이 가능한가요?
|
|
41
|
+
>
|
|
42
|
+
> — @woowajames on `src/test/kotlin/domainTest/gameTest/GameBaseTest.kt`
|
|
43
|
+
|
|
44
|
+
> 테스트를 위한 클래스일 뿐 실제로 어떤 테스트를 하는 클래스는 아니라서 네이밍만 보면 혼란스러울 것 같습니다.
|
|
45
|
+
>
|
|
46
|
+
> — @woowajames on `src/test/kotlin/domainTest/GameBaseTest.kt`
|
|
47
|
+
|
|
48
|
+
## 얻은 교훈
|
|
49
|
+
|
|
50
|
+
- **data class는 "데이터를 모으는 가치"가 있을 때만.** 두 검증기를 단순 wrapping하는 data class는 equals/hashCode/copy/toString을 자동 생성해 봤자 그 의미가 없다. 의미 없는 그룹화는 추상의 가치를 만들지 않는다.
|
|
51
|
+
- **이름의 품사가 객체의 정체성을 결정한다.** `Validate-`는 동사 — 함수처럼 느껴진다. `Validator`는 명사 — 객체로 느껴진다. 객체지향에서는 명사형이 자연스럽다.
|
|
52
|
+
- **테스트 부모 클래스의 trade-off.** 공통 setup의 재사용성 vs 케이스의 유연성. 모든 시나리오에서 같은 setup이 맞다면 부모 클래스, 케이스별로 다른 데이터가 필요하면 각자 만들기.
|
|
53
|
+
- **테스트 코드의 명명/위치 = production의 거울.** `XxxTest` 규칙, production 패키지 구조 mirror가 일반적. `domainTest`라는 패키지에 Controller가 들어가면 거울이 깨진다.
|
|
54
|
+
- **헬퍼 클래스의 이름은 헬퍼임을 드러내야 한다.** `GameBaseTest`라는 이름은 "테스트 클래스"로 보인다. `GameTestSupport` 등 헬퍼임을 명시하는 게 안전.
|
|
55
|
+
- **리뷰어가 "옮기라는 의미가 아니었다"고 두 번 정정한 패턴** — 학생이 코멘트를 다르게 받아들이는 경우가 흔하다. 학생이 의도를 자기 언어로 다시 적어 확인받는 응답 패턴이 학습 정확성을 높인다.
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# PR #54 — [자동차 경주] 브리 미션 제출합니다
|
|
2
|
+
|
|
3
|
+
- **Reviewee:** [@briandr97](https://github.com/briandr97)
|
|
4
|
+
- **PR:** https://github.com/woowacourse/kotlin-racingcar/pull/54
|
|
5
|
+
- **단계:** 1단계 (단일 PR)
|
|
6
|
+
- **리뷰어:** @galcyurio
|
|
7
|
+
- **라인 코멘트:** 12
|
|
8
|
+
|
|
9
|
+
## 잘한 점 (설계 관점)
|
|
10
|
+
|
|
11
|
+
- **`Driver` 도메인 도입** — 차량이 운전자를 가짐. "현실 같은 설계" 리뷰어 칭찬.
|
|
12
|
+
- **`Referee` object**, `TestCarFactory` 테스트 헬퍼 분리.
|
|
13
|
+
- **PR에 자가 의문 풍부**.
|
|
14
|
+
|
|
15
|
+
## 못한 점 (설계 관점)
|
|
16
|
+
|
|
17
|
+
- **`DriverDecision`이 util 패키지에** — 도메인 중요 결정 로직이 util이 아님.
|
|
18
|
+
- **`Car.move()` 대신 `drive()` 같은 모호한 이름** — Driver가 결정한 후 차량은 그냥 *움직임*.
|
|
19
|
+
- **테스트 케이스 이름 모호** — 분기처리 들어간 테스트 = 두 테스트로 분리.
|
|
20
|
+
- **`object Referee` 적절한지** — 상태 없는 유틸 형태로만 쓰이면 OK.
|
|
21
|
+
|
|
22
|
+
## 리뷰어 의견 요지
|
|
23
|
+
|
|
24
|
+
리뷰어 @galcyurio의 가르침:
|
|
25
|
+
|
|
26
|
+
1. **object 사용 기준 = 상태 무 + Util성** — "보통 Util성 함수만 object. 유지보수하다보면 상태/의존성 생겨버리기 때문."
|
|
27
|
+
|
|
28
|
+
2. **차량이 driver를 가짐 = 현실 모델링 잘됨**. Driver가 판단, Car는 움직임.
|
|
29
|
+
|
|
30
|
+
3. **함수명 = *그 객체의 행위 관점*** — 판단은 Driver, 움직임은 Car. → `move()`가 자연스러움.
|
|
31
|
+
|
|
32
|
+
4. **도메인 vs util 패키지** — "차량이 움직일지를 결정하는 중요한 도메인이므로 domain에 위치."
|
|
33
|
+
|
|
34
|
+
5. **테스트에 분기 = 두 테스트로 분리**. "테스트에서는 분기가 안 나와야."
|
|
35
|
+
|
|
36
|
+
6. **요구사항 = 테스트 케이스 이름 그대로**. "이름이 1~5 범위 안/밖" 같은 시나리오를 그대로.
|
|
37
|
+
|
|
38
|
+
- **대표 인용:**
|
|
39
|
+
> 차량이 driver를 가지고 있네요. 설계가 현실같아서 재미있네요 :) 움직일지 판단하는 것은 Driver가 처리했고 차량 입장에서는 움직이는 것이니까 move() 와 같은 함수명이 더 어울리지 않을까요?
|
|
40
|
+
>
|
|
41
|
+
> — @galcyurio on `src/main/kotlin/domain/Car.kt`
|
|
42
|
+
|
|
43
|
+
> 테스트 코드에서는 분기처리가 나오지 않아야 합니다. 만약 분기처리가 필요하다고 생각되면, 2개의 테스트 케이스가 되어야 하는게 아닌지 고민해보세요.
|
|
44
|
+
>
|
|
45
|
+
> — @galcyurio on `src/test/kotlin/domain/CarTest.kt`
|
|
46
|
+
|
|
47
|
+
> 차량이 움직일지를 결정하는 중요한 도메인이기 때문에 domain 패키지에 위치해야 합니다.
|
|
48
|
+
>
|
|
49
|
+
> — @galcyurio on `src/main/kotlin/util/DriverDecision.kt`
|
|
50
|
+
|
|
51
|
+
## 얻은 교훈
|
|
52
|
+
|
|
53
|
+
- **현실 모델링의 가치 = 협력의 자연스러움**. Driver-Car 관계처럼 *현실에 있는* 협력자가 코드에 들어오면 책임이 자연스럽게 갈림.
|
|
54
|
+
- **함수명 = *그 객체의 시점***. Driver는 *판단*, Car는 *움직임*. Car.drive()는 어색, Car.move()가 자연.
|
|
55
|
+
- **util 패키지의 함정** — 도메인 결정 로직을 util에 두면 "이건 보조다"라는 잘못된 신호. 도메인 결정은 domain에.
|
|
56
|
+
- **테스트에 if/when = 두 테스트로 쪼개라**. 한 테스트가 두 경로를 *둘 다* 검증하면 어느 경로 실패인지 모름.
|
|
57
|
+
- **요구사항 = 테스트 함수명**. 도메인 요구사항을 그대로 쓰면 *문서로서의 테스트* 효과.
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# PR #131 — [자동차 경주 리팩터링] 채채 미션 제출합니다
|
|
2
|
+
|
|
3
|
+
- **Reviewee:** [@chaehyuns](https://github.com/chaehyuns)
|
|
4
|
+
- **PR:** https://github.com/woowacourse/kotlin-racingcar/pull/131
|
|
5
|
+
- **단계:** 리팩터링
|
|
6
|
+
- **리뷰어:** @malibinYun
|
|
7
|
+
- **라인 코멘트:** 5 (1단계 큰 피드백을 정리하는 라운드)
|
|
8
|
+
|
|
9
|
+
## 잘한 점 (설계 관점)
|
|
10
|
+
|
|
11
|
+
- **1단계의 피드백 일부 반영** — RaceService 도입 등.
|
|
12
|
+
- **ExceptionTest로 예외 시나리오 분리**.
|
|
13
|
+
|
|
14
|
+
## 못한 점 (설계 관점)
|
|
15
|
+
|
|
16
|
+
- **`RacingCarController.run`이 도메인 라운드 진행 로직을 직접 수행** — 자동차를 원하는 라운드 수만큼 주행시키는 것은 도메인. 핵심 미션은 그 로직을 도메인 객체로 분리.
|
|
17
|
+
- **`Car.forward()`가 여전히 테스트만을 위한 코드** — `tryForward()`로 대체 가능한데 유지. 1단계 피드백 미흡 반영.
|
|
18
|
+
- **`RacingService`와 `WinnerService`가 같은 `List<Car>`를 다룸** — 일급 컬렉션(Cars)으로 묶을 자리에 service 두 개.
|
|
19
|
+
- **`EmptySource`로 공백 검증** — `\n` 등 whitespace 누락. 도메인 invariants 정의 좁음.
|
|
20
|
+
- **테스트가 Car의 초기 위치를 생성 시 받지 못함** — 결정적 시나리오 빌드 어려움.
|
|
21
|
+
|
|
22
|
+
## 리뷰어 의견 요지
|
|
23
|
+
|
|
24
|
+
리뷰어 @malibinYun는 **"라운드 진행은 도메인 로직"** 이라는 핵심 가이드를 반복. Controller에서 그 로직을 도메인 객체로 분리하는 것이 이 미션의 가장 핵심이라는 명시. 그리고 도메인 로직에 View 구현이 새지 않도록 설계할 것.
|
|
25
|
+
|
|
26
|
+
또한 **"이전 피드백이 여전히 유효"** 라는 반복 인용 — 학생이 흡수 못한 가이드를 강조. `Car.forward()` 메서드를 테스트만 위해 두는 패턴, `List<Car>`를 도메인 객체로 묶는 패턴 모두 이전 라운드부터 유효.
|
|
27
|
+
|
|
28
|
+
`EmptySource`의 의미에 대해서도 정밀하게 — 모든 공백 문자가 아니라 빈 문자열만 제공한다는 점을 짚어 도메인 invariants 정의를 확장하라는 가이드.
|
|
29
|
+
|
|
30
|
+
- **대표 인용:**
|
|
31
|
+
> 자동차를 원하는 라운드의 수 만큼 주행을 하게 만드는 것은 도메인 로직이에요! 이 도메인 로직을 분리해내는 게 이 미션에서 가장 핵심이 되겠네요.
|
|
32
|
+
>
|
|
33
|
+
> — @malibinYun on `src/main/kotlin/racingcar/controller/RacingCarController.kt:38`
|
|
34
|
+
|
|
35
|
+
> List<Car>를 가지고 수행하는 역할들을 잘 모아서 하나의 객체로 표현해보는 건 어떨까요?
|
|
36
|
+
>
|
|
37
|
+
> — @malibinYun on `src/main/kotlin/racingcar/service/WinnerService.kt:5`
|
|
38
|
+
|
|
39
|
+
> EmptySource에는 사실 모든 공백 문자열을 파라미터로 제공해주는 게 아니랍니다 ... `\n` 등 다른 공백 문자들도 테스트를 진행해보셔도 좋겠어요.
|
|
40
|
+
>
|
|
41
|
+
> — @malibinYun on `src/test/kotlin/racingcar/ExceptionTest.kt:16`
|
|
42
|
+
|
|
43
|
+
## 얻은 교훈
|
|
44
|
+
|
|
45
|
+
- **라운드 진행은 게임의 본질 = 도메인 로직.** Controller가 라운드 루프를 돌리면 그것이 Controller의 책임이 되어 도메인 객체가 데이터 컨테이너로 격하. 게임이 게임을 진행해야.
|
|
46
|
+
- **이전 피드백의 일관 적용이 학습 척도.** 리뷰어가 같은 코멘트를 다시 인용하면, 학생이 그 가이드를 흡수하지 못한 신호. 단순 코드 수정이 아니라 이해와 적용이 필요.
|
|
47
|
+
- **`List<X>`를 여러 service가 각각 다룬다 = 일급 컬렉션 신호.** `Cars` 객체가 `move`, `findWinners` 등 List 자체의 책임을 다 가지면 service들이 사라진다.
|
|
48
|
+
- **EmptySource의 범위.** JUnit의 EmptySource는 빈 문자열만 제공. whitespace(`\t`, `\n`, ` `)는 별도 데이터 제공자(@NullAndEmptySource + ValueSource) 필요. 명세를 좁게 받아들이지 말 것.
|
|
49
|
+
- **테스트 가능성을 위한 초기 상태 주입.** Car의 position을 생성자로 받게 만들면 결정적 시나리오 작성 가능. 이건 1단계부터 반복된 가이드 — 학생이 흡수해야 할 핵심.
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# PR #99 — [자동차 경주 구현] 채채 미션 제출합니다
|
|
2
|
+
|
|
3
|
+
- **Reviewee:** [@chaehyuns](https://github.com/chaehyuns)
|
|
4
|
+
- **PR:** https://github.com/woowacourse/kotlin-racingcar/pull/99
|
|
5
|
+
- **단계:** 1단계
|
|
6
|
+
- **리뷰어:** @malibinYun
|
|
7
|
+
- **라인 코멘트:** 31
|
|
8
|
+
|
|
9
|
+
## 잘한 점 (설계 관점)
|
|
10
|
+
|
|
11
|
+
- **README에 기능 요구사항 상세 정리** — 리뷰어 칭찬.
|
|
12
|
+
- **자기 의문을 명확히 정리** — private 기준, validator 위치, object/class 선택 등 메타 토론.
|
|
13
|
+
- **상수 분류 시도** — Game/Output/Error 관련 상수 별도 파일.
|
|
14
|
+
|
|
15
|
+
## 못한 점 (설계 관점)
|
|
16
|
+
|
|
17
|
+
- **상수를 `GameConstants`, `ErrorConstants` 등 여러 파일로 분산** — 같은 도메인의 상수가 여러 파일에 흩어짐. 결국 카테고리 경계가 모호 (게임 에러는 어디?).
|
|
18
|
+
- **`InputValidator`로 도메인 검증을 입력 경계에 집중** — `Car("아무튼비정상적인이름")`이 생성되어 프로그램을 돌아다닐 수 있음. invariants의 자리 어긋남.
|
|
19
|
+
- **`ForwardService`가 자동차를 받아 직접 움직임** — 외부에서 객체 조종. Tell-Don't-Ask 위반.
|
|
20
|
+
- **`Car.forwardCount`를 setter 차단하려고 가시성 변경자 사용** — `private set`이 더 단순.
|
|
21
|
+
- **`compareTo`로 자동차 비교 테스트** — `car1.compareTo(car2) == 0`이 무엇을 의미하는지 코드 안 본 사람은 모름.
|
|
22
|
+
- **`RacingCarController`가 비대** — 시도 횟수를 직접 다룸. 현실 세계 비유 부재.
|
|
23
|
+
|
|
24
|
+
## 리뷰어 의견 요지
|
|
25
|
+
|
|
26
|
+
리뷰어 @malibinYun는 **"현실 세계 비유로 객체를 만들어보기"** 를 강하게 제시. "시도 횟수가 여러 action을 하게 하는 것"은 현실에서 찾기 어려움. "경주장에 자동차들이 있고, 경주장에 메시지 던져 경기 시작"이 자연스러움. 학생이 RaceService라는 단어를 쓴 것에 대해 "경주장"이라는 도메인 어휘로의 전환을 제안.
|
|
27
|
+
|
|
28
|
+
또한 **"InputView를 떼고도 도메인이 유효한가?"** 라는 강력한 시뮬레이션 — Car의 invariants가 input 경계에만 있으면, 다른 플랫폼(안드로이드 등)에서 input 없이 Car 생성 시 무방비.
|
|
29
|
+
|
|
30
|
+
상수 분류에 대해서는 **"카테고리도 결국 모호해진다"** 는 가이드 + 학생의 결정 존중("스스로 결정하게 된 이유를 잘 가져가보길 바라요").
|
|
31
|
+
|
|
32
|
+
- **대표 인용:**
|
|
33
|
+
> 시도 횟수가 어려번의 action을 하게하는 것.. 이것은 현실세계에서 찾기에는 어려워보여요. 경주를 위해 자동차들이 달릴 경주장을 객체로 표현해보는 건 어떨까요?
|
|
34
|
+
>
|
|
35
|
+
> — @malibinYun on `src/main/kotlin/racingcar/controller/RacingCarController.kt`
|
|
36
|
+
|
|
37
|
+
> inputView를 사용하지 않게 된다면 어떻게 될까요? 이 로직을 모두 안드로이드 프로젝트에 옮기면 ... 이때 Car("아무튼비정상적인이름")를 생성자를 통해 생성한다면, 이 Car 객체는 프로그램에서 돌아다녀도 괜찮은 유효한 객체일까요?
|
|
38
|
+
>
|
|
39
|
+
> — @malibinYun on `src/main/kotlin/racingcar/view/input/InputValidator.kt`
|
|
40
|
+
|
|
41
|
+
> 다른 객체가 자동차를 받아서 검증 후 직접 움직이게도 할 수 있지만, 자동차에게 숫자를 주어서 자율적으로 움직일지 말지 역할을 부여해보는 건 어떨까요?
|
|
42
|
+
>
|
|
43
|
+
> — @malibinYun on `src/main/kotlin/racingcar/service/ForwardService.kt`
|
|
44
|
+
|
|
45
|
+
## 얻은 교훈
|
|
46
|
+
|
|
47
|
+
- **다른 플랫폼으로 옮기는 시뮬레이션 = 결합도 진단.** "InputView 없이 도메인을 콘솔/안드로이드/웹에 옮기면 어떨까?"라는 질문이 입력 결합도를 즉시 보여줌. 도메인이 자기 invariants를 가지면 매체와 무관하게 유효.
|
|
48
|
+
- **현실 세계 비유는 책임 위치의 발견 도구.** "경주장이 자동차들에게 경기를 시작하라"가 현실의 책임 구조. 그 비유로 RaceService → RaceTrack/RacingGame 도메인 객체로의 전환.
|
|
49
|
+
- **상수 분류 카테고리도 결국 모호해진다.** GameConstants vs ErrorConstants 사이에서 "게임 에러"가 어디 갈지 모호. 응집의 진짜 답은 "그 상수의 사용자가 가짐".
|
|
50
|
+
- **`compareTo` 사용은 도메인 의미가 있을 때만.** 자동차에 자연스러운 순서가 있다면 OK, 단순 비교에 `compareTo`를 쓰면 호출자가 0/양수/음수의 의미를 알아야.
|
|
51
|
+
- **자기 결정의 이유를 가져가는 것의 가치.** 같은 문제에 다른 답을 선택해도 그 이유를 가져가면 다음 결정에서 활용 가능. 리뷰어가 "내 답이 정답"이 아니라 "이유를 가져가라"는 메타 가이드는 학생의 자율 학습 능력을 키운다.
|
|
52
|
+
- **객체에 메시지 던지기 = 자율성 부여.** ForwardService가 자동차를 검증하고 직접 움직이면, 자동차의 자율성이 떼어져 나간다. `car.move(number)` 메시지로 결정권을 자동차에게.
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# PR #147 — [자동차 경주 구현] 페토 미션 제출합니다
|
|
2
|
+
|
|
3
|
+
- **Reviewee:** [@chanho0908](https://github.com/chanho0908)
|
|
4
|
+
- **PR:** https://github.com/woowacourse/kotlin-racingcar/pull/147
|
|
5
|
+
- **단계:** 1단계
|
|
6
|
+
- **리뷰어:** @hyemdooly
|
|
7
|
+
- **라인 코멘트:** 47
|
|
8
|
+
|
|
9
|
+
## 잘한 점 (설계 관점)
|
|
10
|
+
|
|
11
|
+
- **Validator를 도메인별로 분리** — `CarNamesValidator` / `RoundsValidator`로 분리해 책임 단위가 명확해진 시도. (다만 분리한 자체 책임이 여전히 미세하게 어긋남)
|
|
12
|
+
- **랜덤을 인터페이스 + functional interface로 주입** — `RandomNumberFactory`를 SAM interface로 만들어 테스트 가능성 확보. 의도와 구현 모두 양호.
|
|
13
|
+
- **`OutputView`에서 가공 책임 분리 시도** — "출력만 한다"는 책임을 지키려 데이터 가공을 Model로 옮긴 의도는 좋음 (단 그 결과로 Model이 출력을 알게 됨 — 다음 라운드의 토론거리).
|
|
14
|
+
- **함수 이름 추상화의 의도 표현** — `increaseOnePositionIfMovable` 같은 구체적 이름 대신 추상적 이름을 의도적으로 선택, 그 trade-off까지 직접 제기.
|
|
15
|
+
- **`value class` 활용으로 도메인 표현** — `Rounds`를 단순 Int가 아니라 의미 있는 타입으로 표현.
|
|
16
|
+
|
|
17
|
+
## 못한 점 (설계 관점)
|
|
18
|
+
|
|
19
|
+
- **`Validator`가 "검증 + 분리"의 두 가지 일을 함** — String 입력을 받아 car 이름으로 split까지 함. 이름은 검증인데 변환도 한다.
|
|
20
|
+
- **`is-` 접두사가 boolean이 아닌 예외 throw 함수에 붙음** — 메서드 이름이 약속을 거짓말함 (`isXxx`라면 호출자는 boolean을 기대).
|
|
21
|
+
- **`Controller`와 `Game`의 역할 중복** — 둘 다 게임 진행에 관여하는데 누가 무엇을 책임지는지 불분명.
|
|
22
|
+
- **View 메시지(에러 등)가 `Retry` 유틸 안에서 출력됨** — 시스템 메시지가 View 책임인데 다른 곳에서 출력하여 책임 분리가 깨짐.
|
|
23
|
+
- **Model이 출력 가공을 함** — Output을 단순화하려고 가공을 Model로 옮겼지만, 결국 "출력 형식 변경"이 Model 변경을 강제하게 됨 — 결합 방향만 바뀐 셈.
|
|
24
|
+
- **테스트 함수 이름이 의도를 안 드러냄** — "전진이 가능하다"가 무엇을 의미하는지 테스트명만 보고 모름. 요구사항 문서로서 가치가 약함.
|
|
25
|
+
- **`Rounds`가 너무 많은 일을 함** — 숫자 변환 + 검증 + invoke 패턴 + companion object validator. "Rounds라는 도메인 개념"이 입력 파싱과 뒤섞임.
|
|
26
|
+
- **Retry 유틸의 위치/책임** — runCatching 같은 표준 도구로 대체 가능하면서, 동시에 View 메시지까지 들고 있어 책임이 모호.
|
|
27
|
+
|
|
28
|
+
## 리뷰어 의견 요지
|
|
29
|
+
|
|
30
|
+
리뷰어 @hyemdooly는 **"이 책임이 여기 있는 게 맞는가"** 를 정말 일관되게 묻는다. Validator의 분리/변환, Controller와 Game의 역할 중복, Model이 출력을 가공하는 흐름 등 책임의 자리에 집요하게 손을 댐. 또한 **"테스트는 요구사항 문서"** 라는 관점을 명시적으로 전달하며 테스트 이름의 도메인 표현을 강조.
|
|
31
|
+
|
|
32
|
+
또한 **"차의 위치를 증가시킨다"가 아니라 "차가 직접 움직인다"** 라는 관점 전환을 짧지만 강력하게 짚어, 객체에게 의인화된 능동성을 부여하는 사고를 안내.
|
|
33
|
+
|
|
34
|
+
- **대표 인용:**
|
|
35
|
+
> 보통 `is-` 접두사가 붙으면 Boolean을 리턴하는 값을 의미하곤 합니다. 이 Validator의 함수들은 모두 검증하고, 만족하지 않을 시 Exception을 던지는 액션을 수행하고 있기 때문에, 검증한다는 의미가 담긴 다른 네이밍이 더 좋지 않을까요?
|
|
36
|
+
>
|
|
37
|
+
> — @hyemdooly on `src/main/kotlin/racingcar/validator/CarNamesValidator.kt`
|
|
38
|
+
|
|
39
|
+
> 출력을 위해 가공한 값은 OutputView의 관심사가 아닐까요? 요구사항이 바뀌어 출력을 수정한다면, Game의 수정도 함께 들어가야할 것 같아요!
|
|
40
|
+
>
|
|
41
|
+
> — @hyemdooly on `src/main/kotlin/racingcar/model/Game.kt:31`
|
|
42
|
+
|
|
43
|
+
> 이 자동차가 현실에 있다고 생각했을 때, 차의 위치를 증가시키기보다는 차가 '직접' 움직인다는 것이 더 자연스러운 이름이지 않을까요?
|
|
44
|
+
>
|
|
45
|
+
> — @hyemdooly on `src/main/kotlin/racingcar/model/Car.kt:14`
|
|
46
|
+
|
|
47
|
+
## 얻은 교훈
|
|
48
|
+
|
|
49
|
+
- **메서드 이름은 호출자와의 약속이다.** `isXxx`는 boolean을 약속한다. 예외를 던지는 동작에 `is-` 접두사를 쓰면 호출자가 잘못된 흐름을 짠다. 약속을 깨지 말 것.
|
|
50
|
+
- **"검증 + 변환"은 분리해야 한다.** 하나는 invariants를 지키는 일, 다른 하나는 형식을 바꾸는 일. 합쳐 두면 둘 중 하나가 바뀔 때 다른 하나가 끌려다닌다.
|
|
51
|
+
- **객체에게 의인화된 능동성을 줘라.** "위치를 증가시키는" 능동자가 외부에 있으면 캡슐화가 깨진다. **"차가 직접 움직인다"** 라는 표현이 그저 미적 차이가 아니라 책임의 위치 차이를 가리킨다.
|
|
52
|
+
- **Model이 출력 가공을 떠맡으면, 결합 방향만 뒤집힌 것이다.** "View는 출력만 한다"를 위해 Model에 가공을 넣으면, 출력 변경이 Model 변경을 강제한다. 가공은 View의 관심사로 남아야 한다.
|
|
53
|
+
- **Controller와 Game이 둘 다 "게임을 진행한다"고 느껴진다면 한쪽의 정체성이 약하다.** 이런 중복은 같은 클래스 둘이 같은 직책을 두고 다투는 것과 같다 — 한 곳으로 모으거나, 둘의 분명한 다른 책임을 정의해야 한다.
|
|
54
|
+
- **값 객체로 만든다고 끝이 아니다.** `Rounds`가 Int를 감쌌지만 그 안에 입력 파싱, 변환, 검증을 모두 넣으면 "단지 무거워진 Int"가 된다. 값 객체의 단순함을 유지하라.
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# PR #160 — [자동차 경주 2단계] 페토 미션 제출합니다
|
|
2
|
+
|
|
3
|
+
- **Reviewee:** [@chanho0908](https://github.com/chanho0908)
|
|
4
|
+
- **PR:** https://github.com/woowacourse/kotlin-racingcar/pull/160
|
|
5
|
+
- **단계:** 2단계
|
|
6
|
+
- **리뷰어:** @hyemdooly
|
|
7
|
+
- **라인 코멘트:** 15
|
|
8
|
+
|
|
9
|
+
## 잘한 점 (설계 관점)
|
|
10
|
+
|
|
11
|
+
- **타입 변환과 도메인 검증 분리 의도 흡수** — String→Int 변환은 입력 경계에서, "2~5자 이름" 같은 도메인 invariants는 도메인 객체에서. 리뷰 후 분리 결정.
|
|
12
|
+
- **`Game`/`Controller` 역할 차이를 명확히 설명** — "사회자(Controller) vs 게임장(Game)"이라는 비유로 자기 설계를 재정의. 리뷰어도 수용.
|
|
13
|
+
- **runCatching 등 표준 도구로 Retry 단순화** — 자체 헬퍼 대신 표준 추상으로 옮김.
|
|
14
|
+
- **블로그 추천을 그대로 따르지 않는 비판적 자세 학습** — "대기업 아티클이라 검증된 줄 알았다"는 회고와 "공식문서 아니면 의심부터"의 가이드 흡수.
|
|
15
|
+
|
|
16
|
+
## 못한 점 (설계 관점)
|
|
17
|
+
|
|
18
|
+
- **`Rounds`의 자기 검증이 여전히 무겁다** — 도메인 요구사항 검증은 OK지만, 검증 로직을 `validate()`로 분리하고 companion object factory invoke까지 얹어 "단순한 값"의 표면적이 커짐. YAGNI 위반 신호.
|
|
19
|
+
- **인터페이스 이름에 구현 단서가 남음** — `RandomNumberGenerator`. 생성 방식이 랜덤일 필요가 없는데 이름이 그렇게 못 박음.
|
|
20
|
+
- **`Validator`를 retry 루프마다 새로 생성** — Validator가 인스턴스 상태를 가져야 할 이유가 없는데 매번 생성. "검증을 action으로" 옮기면 사라질 비용.
|
|
21
|
+
- **테스트 이름이 함수명을 노출** — `playRound가 실행될 때 ...`처럼 테스트가 어떤 시그니처를 호출하는지 드러내면, 그 함수가 리네임되면 테스트가 진실에서 멀어진다.
|
|
22
|
+
- **`Regex` 같은 비싼 객체가 메서드 안에서 매번 생성** — 캡슐화는 OK지만 비용 측면에서 invariant한 객체는 companion으로 끌어올려야.
|
|
23
|
+
|
|
24
|
+
## 리뷰어 의견 요지
|
|
25
|
+
|
|
26
|
+
리뷰어 @hyemdooly는 이 라운드에서 **"수용 vs 자기 판단"** 의 메타 가이드를 강하게 전달했다. "기술 블로그도 무조건 정답은 아니다", "리뷰어의 말이 늘 정답은 아니다 — 페토만의 생각을 정립하라"는 식으로 학습 자세를 정렬.
|
|
27
|
+
|
|
28
|
+
기술적으로는 (1) 도메인이 알아야 할 검증과 input 경계 검증의 분리, (2) `fun interface`가 `() -> Int`와 다를 게 없을 수 있다는 추상화 비용 지적, (3) 추상의 이름이 구현을 노출하는 문제, (4) 테스트 함수 이름이 호출하는 함수 이름을 드러내는 안티패턴을 짚었다.
|
|
29
|
+
|
|
30
|
+
- **대표 인용:**
|
|
31
|
+
> 자료형 변환은 input에서 해결을 하고, 2자~5자와 같은 도메인의 요구사항은 도메인 객체에서 해결하는 편입니다! ... companion object에 검증 로직이 몰려있는데, Rounds라는 도메인 자체의 검증과는 멀어보여서 이 곳에 이 로직들이 있어야하는지 의문이 들어요.
|
|
32
|
+
>
|
|
33
|
+
> — @hyemdooly on `src/main/kotlin/racingcar/model/Rounds.kt`
|
|
34
|
+
|
|
35
|
+
> 이 숫자를 만드는 친구는 랜덤이 아닐 수도 있지 않을까요?
|
|
36
|
+
>
|
|
37
|
+
> — @hyemdooly on `src/main/kotlin/racingcar/model/random/RandomNumberGenerator.kt`
|
|
38
|
+
|
|
39
|
+
> 어떤 함수를 테스트하고자 명시적으로 표현하기 위해 함수 이름을 적은 것은 이해되지만 ... `playRound`의 로직이 바뀌면 결과값도 바뀔 가능성이 있다고 생각해서요!
|
|
40
|
+
>
|
|
41
|
+
> — @hyemdooly on `src/test/kotlin/racingcar/GameTest.kt`
|
|
42
|
+
|
|
43
|
+
## 얻은 교훈
|
|
44
|
+
|
|
45
|
+
- **검증의 자리를 두 단계로 본다.** 형식 변환(String↔Int 등)은 입력 경계에서. 도메인 invariants(이름 길이, 라운드 범위)는 도메인 객체에서. 두 가지를 한 곳에 섞으면 도메인이 입력 형식 변경에 끌려다닌다.
|
|
46
|
+
- **추상화도 비용이다.** `fun interface`가 `() -> Int`와 같은 일을 한다면 추상의 가치가 크지 않다. 추상은 "다른 구현이 정말로 등장할 때"가 가장 강력하다.
|
|
47
|
+
- **이름은 What, 구현은 How.** `RandomNumberGenerator`처럼 How를 이름에 박지 말 것. 향후 `SequentialNumberGenerator`, `FakeNumberGenerator`가 등장할 자리를 미리 비워둘 것.
|
|
48
|
+
- **테스트 이름은 도메인 의도여야 한다.** "playRound 실행 시 ..."는 함수 시그니처에 결합된 테스트 이름. 함수가 리네임되면 테스트가 거짓말을 하기 시작한다. "가장 많이 이동한 사람이 우승한다" 같은 요구사항 표현이 살아남는다.
|
|
49
|
+
- **권위에 의지하는 학습은 위험하다.** 블로그가 아무리 큰 회사 것이어도 자기 상황에 맞는지 의심해야 한다. 리뷰어의 말조차 그렇다. — 이건 조영호님이 강의에서 말한 "케이스 바이 케이스, 경험과 우선순위"와 정확히 맞물린다.
|
|
50
|
+
- **불변 비용 객체는 클래스 수준에 올려라.** Regex나 무거운 lookup 같은 invariant는 메서드 호출마다 새로 만들 일이 아니다. 캡슐화는 위치의 문제이지 매번 생성의 의미가 아님.
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# PR #45 — [스캇] 코틀린 레이싱카 제출합니다
|
|
2
|
+
|
|
3
|
+
- **Reviewee:** [@chws0508](https://github.com/chws0508)
|
|
4
|
+
- **PR:** https://github.com/woowacourse/kotlin-racingcar/pull/45
|
|
5
|
+
- **단계:** 1단계
|
|
6
|
+
- **리뷰어:** @galcyurio
|
|
7
|
+
- **라인 코멘트:** 26
|
|
8
|
+
|
|
9
|
+
## 잘한 점 (설계 관점)
|
|
10
|
+
|
|
11
|
+
- **MVC 의식적 적용**.
|
|
12
|
+
- **자기 의문 깊이** — 논리 오류 vs 예외, Controller 테스트 필요성, 재입력 처리 등.
|
|
13
|
+
- **`val`/`private set` 적절 활용** — 리뷰어 칭찬.
|
|
14
|
+
|
|
15
|
+
## 못한 점 (설계 관점)
|
|
16
|
+
|
|
17
|
+
- **`InputValidationTest`라는 명명** — Exception이 아닌데 Exception처럼 보임.
|
|
18
|
+
- **`try-catch`로 재입력 처리** — 예외를 흐름 제어로.
|
|
19
|
+
- **테스트 이름 추상** — 요구사항 명세화 부족.
|
|
20
|
+
- **Service 테스트가 String 검증** — UI 결합. 도메인 객체 비교가 자연스러움.
|
|
21
|
+
- **`Car`의 매직 넘버 4 인라인**.
|
|
22
|
+
- **`expression body` 함수에 반환 타입 생략** — 의도치 않은 변경 위험.
|
|
23
|
+
- **`DomainTest`라는 명명** — 어떤 클래스의 테스트인지 안 드러남.
|
|
24
|
+
- **테스트 패키지가 production과 다름**.
|
|
25
|
+
|
|
26
|
+
## 리뷰어 의견 요지
|
|
27
|
+
|
|
28
|
+
리뷰어 @galcyurio는 **Elizarov의 코틀린 예외 처리 가이드** 를 명시적으로 인용:
|
|
29
|
+
1. 논리 오류일 때만 예외
|
|
30
|
+
2. 논리 오류 아니면 null
|
|
31
|
+
3. 복잡하면 sealed class
|
|
32
|
+
4. 일반 코드에서 try-catch 지양
|
|
33
|
+
|
|
34
|
+
학생의 깊은 자기 의문에 대해 명확히 답:
|
|
35
|
+
- "5글자 초과는 충분히 예상 가능 → 예외 아님 → null 또는 다른 표현"
|
|
36
|
+
- "Random을 매개변수로 받기 (canMove: Boolean) 또는 전략 패턴"
|
|
37
|
+
- "Controller도 비즈니스 로직 있으면 테스트. InputView/OutputView를 class면 단위 테스트 어렵게 만듦"
|
|
38
|
+
|
|
39
|
+
또한 **expression body 함수의 반환 타입 생략 위험** — 타입 추론 변경이 컴파일 에러 없이 의도와 다른 동작 가능.
|
|
40
|
+
|
|
41
|
+
- **대표 인용:**
|
|
42
|
+
> 논리 오류일 때만 예외를 던지세요 ... 일반적인 코틀린 코드에서 try-catch를 사용하지 마세요.
|
|
43
|
+
>
|
|
44
|
+
> — @galcyurio on `src/test/kotlin/InputValidationTest.kt`
|
|
45
|
+
|
|
46
|
+
> 5글자가 넘는 경우는 충분히 예상 가능한 상황이기 때문에 예외 상황이라고 볼 수 없습니다.
|
|
47
|
+
>
|
|
48
|
+
> — @galcyurio on `src/test/kotlin/InputValidationTest.kt`
|
|
49
|
+
|
|
50
|
+
> 무작위성(Random)을 테스트에서 제외하기 위해서는 무작위성을 매개변수로 받으면 됩니다. `canMove: Boolean`과 같이 받고 외부에서 Random을 통해 결정지어보면 어떨까요?
|
|
51
|
+
>
|
|
52
|
+
> — @galcyurio on `src/test/kotlin/DomainTest.kt`
|
|
53
|
+
|
|
54
|
+
## 얻은 교훈
|
|
55
|
+
|
|
56
|
+
- **예외는 진짜 예외에만.** 사용자 입력 형식 오류 같은 "예상 가능"한 케이스는 null/Result/sealed로 표현. try-catch가 흐름 제어로 쓰이면 안티패턴.
|
|
57
|
+
- **무작위성을 매개변수로 격리.** `canMove: Boolean` 같은 추상 입력으로 결정 위임. 도메인은 무작위 표현 모름.
|
|
58
|
+
- **Expression body의 타입 생략 위험.** 추론 변경이 컴파일 에러 없이 다른 동작. 명시적 반환 타입이 안전.
|
|
59
|
+
- **테스트 클래스명 = production 클래스명 + Test.** `DomainTest`처럼 추상 명명은 무엇의 테스트인지 모호.
|
|
60
|
+
- **Service/Controller 테스트가 String 검증은 UI 결합.** 도메인 객체 비교로 의도 명확화.
|
|
61
|
+
- **자기 의문이 리뷰어의 명확한 답을 끌어냄.** 학생이 자기 모델을 적극 표명하면 리뷰어가 그것을 보강할 수 있는 토론이 만들어진다.
|