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,131 @@
|
|
|
1
|
+
import { assertHasMultipleRemedies } from "./findings.js";
|
|
2
|
+
// 전략(Strategy) 인터페이스의 *공통 시그니처*에 *분기 인자*가 섞이는 안티패턴.
|
|
3
|
+
// 대표 사례: interface LottoMachine { fun generate(count, lottoNumbers: List<List<Int>>? = null) }
|
|
4
|
+
// → ManualLottoMachine은 lottoNumbers를 쓰고, AutomaticLottoMachine은 항상 null을 받음.
|
|
5
|
+
// 설계 모델만으로는 메서드 시그니처를 볼 수 없으므로,
|
|
6
|
+
// "같은 *전략 suffix*를 공유하는 2개 이상의 ServiceProvider가 *knowing의 비대칭*을 보일 때"를 프록시로 잡는다.
|
|
7
|
+
// 근거: @krrong (lotto PR #144) — "공통 인터페이스 = 공통 시그니처. 분기 인자는 생성자".
|
|
8
|
+
const STRATEGY_SUFFIXES = [
|
|
9
|
+
"Machine",
|
|
10
|
+
"Generator",
|
|
11
|
+
"Strategy",
|
|
12
|
+
"Policy",
|
|
13
|
+
"Provider",
|
|
14
|
+
"Handler",
|
|
15
|
+
"Resolver",
|
|
16
|
+
"Selector",
|
|
17
|
+
];
|
|
18
|
+
function endsWithStrategySuffix(name) {
|
|
19
|
+
for (const s of STRATEGY_SUFFIXES) {
|
|
20
|
+
if (name.length > s.length && name.endsWith(s))
|
|
21
|
+
return s;
|
|
22
|
+
}
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
function isStrategyStereotype(card) {
|
|
26
|
+
return card.stereotype === "ServiceProvider" || card.stereotype === "Coordinator";
|
|
27
|
+
}
|
|
28
|
+
export function checkStrategyAsymmetry(design) {
|
|
29
|
+
const out = [];
|
|
30
|
+
// suffix 별로 카드 그룹핑
|
|
31
|
+
const groups = new Map();
|
|
32
|
+
for (const card of design.classes) {
|
|
33
|
+
if (!isStrategyStereotype(card))
|
|
34
|
+
continue;
|
|
35
|
+
const suffix = endsWithStrategySuffix(card.name);
|
|
36
|
+
if (!suffix)
|
|
37
|
+
continue;
|
|
38
|
+
const list = groups.get(suffix) ?? [];
|
|
39
|
+
list.push(card);
|
|
40
|
+
groups.set(suffix, list);
|
|
41
|
+
}
|
|
42
|
+
for (const [suffix, members] of groups) {
|
|
43
|
+
if (members.length < 2)
|
|
44
|
+
continue;
|
|
45
|
+
const knowingCounts = members.map((m) => m.responsibilities.knowing.length);
|
|
46
|
+
const minK = Math.min(...knowingCounts);
|
|
47
|
+
const maxK = Math.max(...knowingCounts);
|
|
48
|
+
// 모두 같은 knowing 갯수면 대칭 — 통과.
|
|
49
|
+
if (minK === maxK)
|
|
50
|
+
continue;
|
|
51
|
+
// 한쪽이 0, 다른쪽이 ≥1 이어야 *분기 인자가 인터페이스에 새는* 시그널.
|
|
52
|
+
if (minK !== 0)
|
|
53
|
+
continue;
|
|
54
|
+
const withData = members.filter((m) => m.responsibilities.knowing.length > 0);
|
|
55
|
+
const empty = members.filter((m) => m.responsibilities.knowing.length === 0);
|
|
56
|
+
out.push(assertHasMultipleRemedies({
|
|
57
|
+
rule_id: "strategy-default-param-pollution",
|
|
58
|
+
severity: "warn",
|
|
59
|
+
target: { kind: "design", id: `strategy-group-${suffix}` },
|
|
60
|
+
message: `${suffix} 전략 그룹(${members.map((m) => m.name).join(", ")})에서 knowing이 *비대칭*입니다. ` +
|
|
61
|
+
`한 구현체(${withData.map((m) => m.name).join(", ")})는 데이터를 보유하지만 ` +
|
|
62
|
+
`다른 구현체(${empty.map((m) => m.name).join(", ")})는 비어 있습니다. ` +
|
|
63
|
+
`공통 인터페이스 메서드가 이 비대칭을 흡수하려고 *nullable 분기 인자*나 *default = emptyList()* 같은 시그니처 오염을 만들 가능성이 높습니다.`,
|
|
64
|
+
evidence: {
|
|
65
|
+
suffix,
|
|
66
|
+
members: members.map((m) => ({
|
|
67
|
+
name: m.name,
|
|
68
|
+
knowing_count: m.responsibilities.knowing.length,
|
|
69
|
+
knowing_sample: m.responsibilities.knowing[0] ?? null,
|
|
70
|
+
})),
|
|
71
|
+
guideline: "@krrong (lotto PR #144): \"수동 발매기의 생성자를 통해 넘겨주는 방식\" — " +
|
|
72
|
+
"공통 인터페이스 = 공통 시그니처. 분기 인자는 *메서드 default*가 아니라 *생성자*로 받아야 한다.",
|
|
73
|
+
},
|
|
74
|
+
remedies: [
|
|
75
|
+
{
|
|
76
|
+
label: "분기 데이터를 *생성자*로 옮기기 (인터페이스 정화)",
|
|
77
|
+
summary: `메서드 시그니처에서 일부 구현체에만 의미 있는 파라미터를 제거하고, ` +
|
|
78
|
+
`해당 데이터는 ${withData[0]?.name ?? "ManualX"}의 *생성자*에서 받는다. ` +
|
|
79
|
+
`인터페이스는 모든 구현체가 *공통으로* 필요한 인자만 노출한다.`,
|
|
80
|
+
tradeoffs: {
|
|
81
|
+
pros: [
|
|
82
|
+
"인터페이스 호출자가 *어떤 구현체인지* 신경 쓰지 않아도 됨",
|
|
83
|
+
"nullable/default 값으로 의미를 *우회 표현*하는 코드 소멸",
|
|
84
|
+
"각 구현체의 *생성 시점*에 자기 의존을 명시 (생성자가 invariant)",
|
|
85
|
+
],
|
|
86
|
+
cons: [
|
|
87
|
+
"구현체 생성 지점에서 인자를 *미리 알아야* 함 (지연 입력이 어려워질 수 있음)",
|
|
88
|
+
"테스트에서 매 구현체마다 생성자 stub 패턴이 달라짐",
|
|
89
|
+
],
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
label: "함수형 인터페이스로 *지연 입력* 끌어올림",
|
|
94
|
+
summary: `인터페이스를 \`(input) -> Output\` 같은 함수형으로 단순화하거나, ` +
|
|
95
|
+
`${withData[0]?.name ?? "ManualX"}의 생성자에 \`() -> List<...>\` 같은 함수를 주입해 ` +
|
|
96
|
+
`*입력 시점*을 호출 컨텍스트로 끌어올린다. @krrong 후속 제안.`,
|
|
97
|
+
tradeoffs: {
|
|
98
|
+
pros: [
|
|
99
|
+
"*매 호출마다 다른 입력*이 필요한 경우 자연스럽게 표현",
|
|
100
|
+
"구현체 생성 시점에 데이터를 알 필요 없음",
|
|
101
|
+
"Kotlin functional interface로 호출자 쪽이 간결",
|
|
102
|
+
],
|
|
103
|
+
cons: [
|
|
104
|
+
"*호출 순서/사이드이펙트*가 함수 내부에 숨음 — 디버깅 비용 증가",
|
|
105
|
+
"함수형 의존이 늘면 *진짜 객체 협력*이 보이지 않게 됨",
|
|
106
|
+
],
|
|
107
|
+
},
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
label: "전략 분리 폐기 + sealed class로 *합치기*",
|
|
111
|
+
summary: `구현체 간 차이가 정말 *데이터의 유무*뿐이라면 인터페이스 대신 sealed class로 합쳐 ` +
|
|
112
|
+
`데이터 보유 케이스와 무보유 케이스를 *타입으로* 표현한다. when 표현식이 모든 케이스를 컴파일 단계에서 강제.`,
|
|
113
|
+
tradeoffs: {
|
|
114
|
+
pros: [
|
|
115
|
+
"케이스가 *닫혀 있음*이 타입에 드러나 when exhaustive 보장",
|
|
116
|
+
"각 케이스가 자기 데이터만 가짐 — 비대칭이 사라짐",
|
|
117
|
+
"*전략이 1~2종에서 끝날* 도메인에 가벼움",
|
|
118
|
+
],
|
|
119
|
+
cons: [
|
|
120
|
+
"변형 추가가 모든 when 분기 수정 비용을 유발 (OCP 약화)",
|
|
121
|
+
"*다형성으로 풀 일을* sealed when으로 풀어 객체지향 의도가 약해짐",
|
|
122
|
+
"외부 라이브러리/외부 의존 주입이 어려워질 수 있음",
|
|
123
|
+
],
|
|
124
|
+
},
|
|
125
|
+
},
|
|
126
|
+
],
|
|
127
|
+
}));
|
|
128
|
+
}
|
|
129
|
+
return out;
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=strategyAsymmetry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"strategyAsymmetry.js","sourceRoot":"","sources":["../../src/validate/strategyAsymmetry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { Design } from "../domain/model.js";
|
|
2
|
+
import type { Finding } from "./findings.js";
|
|
3
|
+
export declare function checkNonNewable(design: Design): Finding[];
|
|
4
|
+
export declare function checkSideEffectInHolder(design: Design): Finding[];
|
|
5
|
+
export declare function checkMockingPressure(design: Design, maxNonNewable: number): Finding[];
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import { assertHasMultipleRemedies } from "./findings.js";
|
|
2
|
+
const NON_NEWABLE_RE = /(Repository|Client|Gateway|Random|Clock|System|Http|Db|Connection)/;
|
|
3
|
+
const STRATEGY_HINT_RE = /(Strategy|Policy|Provider|Source|Generator)/;
|
|
4
|
+
const SIDE_EFFECT_VERBS = /(save|store|persist|send|publish|emit|print|log|write|delete|fetch|call)/i;
|
|
5
|
+
function isNonNewableName(name) {
|
|
6
|
+
return NON_NEWABLE_RE.test(name);
|
|
7
|
+
}
|
|
8
|
+
function hasStrategySeam(card) {
|
|
9
|
+
return card.collaborators.some((c) => STRATEGY_HINT_RE.test(c.name));
|
|
10
|
+
}
|
|
11
|
+
export function checkNonNewable(design) {
|
|
12
|
+
const out = [];
|
|
13
|
+
for (const card of design.classes) {
|
|
14
|
+
const offenders = card.collaborators.filter((c) => isNonNewableName(c.name));
|
|
15
|
+
if (offenders.length === 0)
|
|
16
|
+
continue;
|
|
17
|
+
if (hasStrategySeam(card))
|
|
18
|
+
continue;
|
|
19
|
+
out.push(assertHasMultipleRemedies({
|
|
20
|
+
rule_id: "non-newable",
|
|
21
|
+
severity: "warn",
|
|
22
|
+
target: { kind: "class", id: card.id },
|
|
23
|
+
message: `${card.name}이(가) 외부 자원성 협력자(${offenders
|
|
24
|
+
.map((o) => o.name)
|
|
25
|
+
.join(", ")})를 직접 사용해 단위테스트에서 단순히 \`new\`로 생성하기 어렵습니다.`,
|
|
26
|
+
evidence: {
|
|
27
|
+
offenders: offenders.map((o) => o.name),
|
|
28
|
+
guideline: "조영호님 기준: new로 생성 가능한가, 사이드이펙트 의존을 강제하는가",
|
|
29
|
+
},
|
|
30
|
+
remedies: [
|
|
31
|
+
{
|
|
32
|
+
label: "Strategy/Provider 인터페이스로 추출",
|
|
33
|
+
summary: "외부 자원 호출을 인터페이스 뒤로 감추고, 테스트에서는 페이크 구현을 주입한다.",
|
|
34
|
+
tradeoffs: {
|
|
35
|
+
pros: ["테스트가 단순해지고 모킹 부담이 사라짐", "구현 교체 용이"],
|
|
36
|
+
cons: ["인터페이스 1개 추가로 코드 표면적 증가"],
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
label: "값(결과)을 파라미터로 받기",
|
|
41
|
+
summary: "자원에서 얻은 값(예: 현재 시각, 난수)을 호출 시점에 파라미터로 받아 객체를 순수하게 유지한다.",
|
|
42
|
+
tradeoffs: {
|
|
43
|
+
pros: ["객체가 완전히 순수해져 테스트 자유도 최고"],
|
|
44
|
+
cons: ["호출자가 값을 준비해야 해서 유스케이스 진입점이 무거워짐"],
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
label: "Interfacer로 위임 + 경계에서만 자원 사용",
|
|
49
|
+
summary: "외부 자원 호출 책임을 별도 Interfacer로 모으고, 도메인 객체는 그 결과만 받는다.",
|
|
50
|
+
tradeoffs: {
|
|
51
|
+
pros: ["도메인-인프라 경계가 명확", "교체 가능한 구조"],
|
|
52
|
+
cons: ["계층이 늘어 학습 곡선 상승"],
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
],
|
|
56
|
+
}));
|
|
57
|
+
}
|
|
58
|
+
return out;
|
|
59
|
+
}
|
|
60
|
+
// UI 표현 문자열이 도메인 데이터에 박혀 있는지 검출. PR #78 (s9hn): DriverDecision.distance="-"
|
|
61
|
+
// UI 변경이 도메인 변경으로 번지는 안티패턴.
|
|
62
|
+
const UI_LITERAL_RE = /["'`]\s*[-|│:\\n→←↑↓\s]+\s*["'`]|["'`]\s*[-=*]{2,}\s*["'`]/;
|
|
63
|
+
export function checkSideEffectInHolder(design) {
|
|
64
|
+
const out = [];
|
|
65
|
+
for (const card of design.classes) {
|
|
66
|
+
if (card.stereotype !== "InformationHolder")
|
|
67
|
+
continue;
|
|
68
|
+
const offenders = card.responsibilities.doing.filter((d) => SIDE_EFFECT_VERBS.test(d));
|
|
69
|
+
const uiLiterals = card.responsibilities.knowing.filter((k) => UI_LITERAL_RE.test(k));
|
|
70
|
+
if (offenders.length === 0 && uiLiterals.length === 0)
|
|
71
|
+
continue;
|
|
72
|
+
const reasons = [];
|
|
73
|
+
if (offenders.length > 0)
|
|
74
|
+
reasons.push(`사이드이펙트성 동사(저장/전송/기록 등) doing 책임 (${offenders.join(", ")})`);
|
|
75
|
+
if (uiLiterals.length > 0)
|
|
76
|
+
reasons.push(`UI 표현 문자열을 knowing에 보유 (${uiLiterals.join(", ")}). ` +
|
|
77
|
+
`UI 변경이 도메인 변경으로 번질 위험이 있습니다.`);
|
|
78
|
+
out.push(assertHasMultipleRemedies({
|
|
79
|
+
rule_id: "side-effect-in-holder",
|
|
80
|
+
severity: "warn",
|
|
81
|
+
target: { kind: "class", id: card.id },
|
|
82
|
+
message: `${card.name}은(는) InformationHolder인데 ${reasons.join(" · ")}.`,
|
|
83
|
+
evidence: { offenders, ui_literals: uiLiterals },
|
|
84
|
+
remedies: [
|
|
85
|
+
{
|
|
86
|
+
label: "Stereotype을 ServiceProvider로 재분류",
|
|
87
|
+
summary: "사이드이펙트 책임이 본질이라면 Stereotype을 맞게 바꾼다.",
|
|
88
|
+
tradeoffs: {
|
|
89
|
+
pros: ["역할이 정확히 표현됨"],
|
|
90
|
+
cons: ["원래 정보 표현 목적이라면 정체성이 흐려짐"],
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
label: "사이드이펙트를 새 ServiceProvider/Interfacer로 추출",
|
|
95
|
+
summary: "정보를 보유하는 책임은 남기고, 저장/전송 등은 새 협력자에게 위임한다.",
|
|
96
|
+
tradeoffs: {
|
|
97
|
+
pros: ["순수한 도메인 정보 보존", "테스트 용이"],
|
|
98
|
+
cons: ["클래스 수 증가"],
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
label: "이벤트로 바꾸고 Interfacer가 처리",
|
|
103
|
+
summary: "사이드이펙트를 이벤트 발행으로 바꾸고 경계에서 Interfacer가 실제 동작을 수행한다.",
|
|
104
|
+
tradeoffs: {
|
|
105
|
+
pros: ["도메인이 인프라를 모름", "확장 용이"],
|
|
106
|
+
cons: ["이벤트 추적이 어려워질 수 있음"],
|
|
107
|
+
},
|
|
108
|
+
},
|
|
109
|
+
],
|
|
110
|
+
}));
|
|
111
|
+
}
|
|
112
|
+
return out;
|
|
113
|
+
}
|
|
114
|
+
export function checkMockingPressure(design, maxNonNewable) {
|
|
115
|
+
const out = [];
|
|
116
|
+
for (const card of design.classes) {
|
|
117
|
+
const nonNewable = card.collaborators.filter((c) => isNonNewableName(c.name));
|
|
118
|
+
if (nonNewable.length <= maxNonNewable)
|
|
119
|
+
continue;
|
|
120
|
+
out.push(assertHasMultipleRemedies({
|
|
121
|
+
rule_id: "mocking-pressure",
|
|
122
|
+
severity: "info",
|
|
123
|
+
target: { kind: "class", id: card.id },
|
|
124
|
+
message: `${card.name}이(가) 외부 자원성 협력자 ${nonNewable.length}개에 의존합니다. ` +
|
|
125
|
+
`테스트에서 모킹 부담이 커집니다.`,
|
|
126
|
+
evidence: { nonNewable: nonNewable.map((n) => n.name), max: maxNonNewable },
|
|
127
|
+
remedies: [
|
|
128
|
+
{
|
|
129
|
+
label: "테스트 더블 seam 도입",
|
|
130
|
+
summary: "모든 외부 의존을 한두 개의 Strategy 인터페이스 뒤로 모은다.",
|
|
131
|
+
tradeoffs: {
|
|
132
|
+
pros: ["모킹 지점이 줄어든다"],
|
|
133
|
+
cons: ["seam 설계에 시간 필요"],
|
|
134
|
+
},
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
label: "조합 책임을 바깥(경계)으로 밀어내기",
|
|
138
|
+
summary: "유스케이스 경계에서 의존성 조립을 하고 도메인 코어는 순수하게 둔다.",
|
|
139
|
+
tradeoffs: {
|
|
140
|
+
pros: ["코어를 표준 단위테스트로 검증 가능"],
|
|
141
|
+
cons: ["조립 책임이 한곳에 집중되어 비대해질 수 있음"],
|
|
142
|
+
},
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
label: "순수 코어 / 인프라 어댑터 분리",
|
|
146
|
+
summary: "도메인 규칙은 순수 객체로, 외부 호출은 어댑터로 나눠 클래스를 둘로 쪼갠다.",
|
|
147
|
+
tradeoffs: {
|
|
148
|
+
pros: ["테스트 피라미드 하단(단위) 비중 증가"],
|
|
149
|
+
cons: ["객체 수 증가, 호출 흐름 길어짐"],
|
|
150
|
+
},
|
|
151
|
+
},
|
|
152
|
+
],
|
|
153
|
+
}));
|
|
154
|
+
}
|
|
155
|
+
return out;
|
|
156
|
+
}
|
|
157
|
+
//# sourceMappingURL=testability.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"testability.js","sourceRoot":"","sources":["../../src/validate/testability.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,yBAAyB,EAAE,MAAM,eAAe,CAAC;AAE1D,MAAM,cAAc,GAAG,oEAAoE,CAAC;AAC5F,MAAM,gBAAgB,GAAG,6CAA6C,CAAC;AACvE,MAAM,iBAAiB,GAAG,2EAA2E,CAAC;AAEtG,SAAS,gBAAgB,CAAC,IAAY;IACpC,OAAO,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACnC,CAAC;AAED,SAAS,eAAe,CAAC,IAAa;IACpC,OAAO,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;AACvE,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,MAAc;IAC5C,MAAM,GAAG,GAAc,EAAE,CAAC;IAC1B,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QAClC,MAAM,SAAS,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QAC7E,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;YAAE,SAAS;QACrC,IAAI,eAAe,CAAC,IAAI,CAAC;YAAE,SAAS;QAEpC,GAAG,CAAC,IAAI,CACN,yBAAyB,CAAC;YACxB,OAAO,EAAE,aAAa;YACtB,QAAQ,EAAE,MAAM;YAChB,MAAM,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE;YACtC,OAAO,EACL,GAAG,IAAI,CAAC,IAAI,mBAAmB,SAAS;iBACrC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;iBAClB,IAAI,CAAC,IAAI,CAAC,4CAA4C;YAC3D,QAAQ,EAAE;gBACR,SAAS,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;gBACvC,SAAS,EAAE,yCAAyC;aACrD;YACD,QAAQ,EAAE;gBACR;oBACE,KAAK,EAAE,6BAA6B;oBACpC,OAAO,EACL,8CAA8C;oBAChD,SAAS,EAAE;wBACT,IAAI,EAAE,CAAC,uBAAuB,EAAE,UAAU,CAAC;wBAC3C,IAAI,EAAE,CAAC,wBAAwB,CAAC;qBACjC;iBACF;gBACD;oBACE,KAAK,EAAE,iBAAiB;oBACxB,OAAO,EACL,yDAAyD;oBAC3D,SAAS,EAAE;wBACT,IAAI,EAAE,CAAC,yBAAyB,CAAC;wBACjC,IAAI,EAAE,CAAC,iCAAiC,CAAC;qBAC1C;iBACF;gBACD;oBACE,KAAK,EAAE,8BAA8B;oBACrC,OAAO,EACL,qDAAqD;oBACvD,SAAS,EAAE;wBACT,IAAI,EAAE,CAAC,gBAAgB,EAAE,WAAW,CAAC;wBACrC,IAAI,EAAE,CAAC,iBAAiB,CAAC;qBAC1B;iBACF;aACF;SACF,CAAC,CACH,CAAC;IACJ,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,4EAA4E;AAC5E,4BAA4B;AAC5B,MAAM,aAAa,GAAG,4DAA4D,CAAC;AAEnF,MAAM,UAAU,uBAAuB,CAAC,MAAc;IACpD,MAAM,GAAG,GAAc,EAAE,CAAC;IAC1B,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QAClC,IAAI,IAAI,CAAC,UAAU,KAAK,mBAAmB;YAAE,SAAS;QACtD,MAAM,SAAS,GAAG,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QACvF,MAAM,UAAU,GAAG,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QACtF,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;YAAE,SAAS;QAEhE,MAAM,OAAO,GAAa,EAAE,CAAC;QAC7B,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC;YACtB,OAAO,CAAC,IAAI,CAAC,oCAAoC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC5E,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC;YACvB,OAAO,CAAC,IAAI,CACV,2BAA2B,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK;gBACnD,8BAA8B,CACjC,CAAC;QAEJ,GAAG,CAAC,IAAI,CACN,yBAAyB,CAAC;YACxB,OAAO,EAAE,uBAAuB;YAChC,QAAQ,EAAE,MAAM;YAChB,MAAM,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE;YACtC,OAAO,EAAE,GAAG,IAAI,CAAC,IAAI,4BAA4B,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG;YACvE,QAAQ,EAAE,EAAE,SAAS,EAAE,WAAW,EAAE,UAAU,EAAE;YAChD,QAAQ,EAAE;gBACR;oBACE,KAAK,EAAE,kCAAkC;oBACzC,OAAO,EAAE,sCAAsC;oBAC/C,SAAS,EAAE;wBACT,IAAI,EAAE,CAAC,aAAa,CAAC;wBACrB,IAAI,EAAE,CAAC,yBAAyB,CAAC;qBAClC;iBACF;gBACD;oBACE,KAAK,EAAE,0CAA0C;oBACjD,OAAO,EACL,0CAA0C;oBAC5C,SAAS,EAAE;wBACT,IAAI,EAAE,CAAC,eAAe,EAAE,QAAQ,CAAC;wBACjC,IAAI,EAAE,CAAC,UAAU,CAAC;qBACnB;iBACF;gBACD;oBACE,KAAK,EAAE,yBAAyB;oBAChC,OAAO,EACL,oDAAoD;oBACtD,SAAS,EAAE;wBACT,IAAI,EAAE,CAAC,cAAc,EAAE,OAAO,CAAC;wBAC/B,IAAI,EAAE,CAAC,mBAAmB,CAAC;qBAC5B;iBACF;aACF;SACF,CAAC,CACH,CAAC;IACJ,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,oBAAoB,CAClC,MAAc,EACd,aAAqB;IAErB,MAAM,GAAG,GAAc,EAAE,CAAC;IAC1B,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QAClC,MAAM,UAAU,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QAC9E,IAAI,UAAU,CAAC,MAAM,IAAI,aAAa;YAAE,SAAS;QACjD,GAAG,CAAC,IAAI,CACN,yBAAyB,CAAC;YACxB,OAAO,EAAE,kBAAkB;YAC3B,QAAQ,EAAE,MAAM;YAChB,MAAM,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE;YACtC,OAAO,EACL,GAAG,IAAI,CAAC,IAAI,mBAAmB,UAAU,CAAC,MAAM,YAAY;gBAC5D,oBAAoB;YACtB,QAAQ,EAAE,EAAE,UAAU,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,aAAa,EAAE;YAC3E,QAAQ,EAAE;gBACR;oBACE,KAAK,EAAE,gBAAgB;oBACvB,OAAO,EACL,wCAAwC;oBAC1C,SAAS,EAAE;wBACT,IAAI,EAAE,CAAC,aAAa,CAAC;wBACrB,IAAI,EAAE,CAAC,gBAAgB,CAAC;qBACzB;iBACF;gBACD;oBACE,KAAK,EAAE,sBAAsB;oBAC7B,OAAO,EACL,wCAAwC;oBAC1C,SAAS,EAAE;wBACT,IAAI,EAAE,CAAC,qBAAqB,CAAC;wBAC7B,IAAI,EAAE,CAAC,2BAA2B,CAAC;qBACpC;iBACF;gBACD;oBACE,KAAK,EAAE,oBAAoB;oBAC3B,OAAO,EACL,6CAA6C;oBAC/C,SAAS,EAAE;wBACT,IAAI,EAAE,CAAC,uBAAuB,CAAC;wBAC/B,IAAI,EAAE,CAAC,oBAAoB,CAAC;qBAC7B;iBACF;aACF;SACF,CAAC,CACH,CAAC;IACJ,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { assertHasMultipleRemedies } from "./findings.js";
|
|
2
|
+
// "Manager", "Util", "Helper" 등 일반 어휘만으로 이루어진 클래스명은 책임 회피의 신호.
|
|
3
|
+
// woowacourse/kotlin-racingcar 133 PR 리뷰에서 가장 빈번하게 지적된 안티패턴 중 하나.
|
|
4
|
+
// 단, 의미 있는 도메인 어휘가 *앞에* 붙으면 책임이 좁혀지므로 허용한다.
|
|
5
|
+
const SUSPECT_SUFFIXES = [
|
|
6
|
+
"Manager",
|
|
7
|
+
"Helper",
|
|
8
|
+
"Util",
|
|
9
|
+
"Utils",
|
|
10
|
+
"Service",
|
|
11
|
+
"Handler",
|
|
12
|
+
"Processor",
|
|
13
|
+
"Worker",
|
|
14
|
+
// 가상 객체 어휘 — 행동을 자기 객체가 아닌 *외부 명사*로 분리하려는 신호.
|
|
15
|
+
// 도메인 객체가 그 책임을 이미 가져야 하는 경우가 대부분.
|
|
16
|
+
"Calculator",
|
|
17
|
+
"Picker",
|
|
18
|
+
"Distributor",
|
|
19
|
+
"Decider",
|
|
20
|
+
"Information",
|
|
21
|
+
"Info",
|
|
22
|
+
];
|
|
23
|
+
// 클래스명 단독으로도 모호한 어휘
|
|
24
|
+
const SUSPECT_STANDALONE = new Set([
|
|
25
|
+
"Validator",
|
|
26
|
+
"Validation",
|
|
27
|
+
"Exception",
|
|
28
|
+
"Common",
|
|
29
|
+
"Const",
|
|
30
|
+
"Constants",
|
|
31
|
+
"Util",
|
|
32
|
+
"Utils",
|
|
33
|
+
"Helper",
|
|
34
|
+
"Manager",
|
|
35
|
+
"Service",
|
|
36
|
+
"Handler",
|
|
37
|
+
// 가상 객체 어휘 (단독 사용 시 god-object 거의 확실)
|
|
38
|
+
"Calculator",
|
|
39
|
+
"Picker",
|
|
40
|
+
"Distributor",
|
|
41
|
+
"Judge",
|
|
42
|
+
"Decider",
|
|
43
|
+
"Information",
|
|
44
|
+
"Info",
|
|
45
|
+
"Rule",
|
|
46
|
+
]);
|
|
47
|
+
function classify(name) {
|
|
48
|
+
if (SUSPECT_STANDALONE.has(name)) {
|
|
49
|
+
return { reason: "suspect-standalone", matched: name };
|
|
50
|
+
}
|
|
51
|
+
for (const suf of SUSPECT_SUFFIXES) {
|
|
52
|
+
if (name === suf)
|
|
53
|
+
return { reason: "suspect-standalone", matched: suf };
|
|
54
|
+
if (name.endsWith(suf)) {
|
|
55
|
+
const prefix = name.slice(0, name.length - suf.length);
|
|
56
|
+
// 의미 있는 prefix (3자 이상의 도메인 단어)는 허용
|
|
57
|
+
if (prefix.length < 3) {
|
|
58
|
+
return { reason: "suspect-suffix-only", matched: suf };
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
export function checkVagueClassName(design) {
|
|
65
|
+
const out = [];
|
|
66
|
+
for (const card of design.classes) {
|
|
67
|
+
const hit = classify(card.name);
|
|
68
|
+
if (!hit)
|
|
69
|
+
continue;
|
|
70
|
+
const message = hit.reason === "suspect-standalone"
|
|
71
|
+
? `${card.name}이라는 이름은 무엇을 하는지 모호합니다. ` +
|
|
72
|
+
`네이밍 모호함은 god-object 안티패턴의 신호일 수 있습니다.`
|
|
73
|
+
: `${card.name}은 "${hit.matched}" 접미사 외에 의미 있는 도메인 어휘가 부족합니다. ` +
|
|
74
|
+
`클래스의 책임이 모호하면 god-object가 될 위험이 있습니다.`;
|
|
75
|
+
out.push(assertHasMultipleRemedies({
|
|
76
|
+
rule_id: "vague-class-name",
|
|
77
|
+
severity: "warn",
|
|
78
|
+
target: { kind: "class", id: card.id },
|
|
79
|
+
message,
|
|
80
|
+
evidence: {
|
|
81
|
+
name: card.name,
|
|
82
|
+
matched_pattern: hit.matched,
|
|
83
|
+
stereotype: card.stereotype,
|
|
84
|
+
guideline: "@vagabond95 (woowacourse-racingcar): \"네이밍이 모호하다는 것은 곧 해당 클래스/함수의 역할이 모호하거나 모호해질 수 있다는 신호\". " +
|
|
85
|
+
"@laco-dev (woowacourse-kotlin-blackjack tobae-time/115): \"현실세계라면 블랙잭 게임의 규칙이지만, 객체지향 세계에서 객체는 모두 스스로 일을 합니다\" — Picker/Distributor/Calculator/Judge 같은 *가상 객체*는 행동을 외부 명사로 분리하려는 신호이며, 도메인 객체가 그 책임을 이미 가져야 한다. " +
|
|
86
|
+
"@ghojeong (woowacourse-kotlin-blackjack kimhm0728/72): \"해당 역할을 컴퓨터가 아니라 사람에게 시키려고 했을 때, 사람이 한 명 더 필요한가\" — 같은 사람이 할 수 있다면 별도 객체로 분리하지 않는다.",
|
|
87
|
+
},
|
|
88
|
+
remedies: [
|
|
89
|
+
{
|
|
90
|
+
label: "무엇을 + 행위로 도메인 어휘 추가",
|
|
91
|
+
summary: `현재 클래스가 *무엇을* 검증/관리/돕는지 이름에 명시한다. ` +
|
|
92
|
+
`예: Validator → InputValidator, Manager → RacingGame, Helper → CarsHelper(여전히 모호하면 다음 안).`,
|
|
93
|
+
tradeoffs: {
|
|
94
|
+
pros: [
|
|
95
|
+
"이름만 보고도 책임 범위가 명확해짐",
|
|
96
|
+
"동료가 IDE 자동완성에서 빠르게 찾을 수 있음",
|
|
97
|
+
],
|
|
98
|
+
cons: [
|
|
99
|
+
"이름이 길어질 수 있음",
|
|
100
|
+
"도메인이 진화하면 이름 갱신 비용",
|
|
101
|
+
],
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
label: "Stereotype에 맞는 역할 이름으로 재명명",
|
|
106
|
+
summary: `현재 stereotype(${card.stereotype})에 맞는 역할 어휘로 바꾼다. ` +
|
|
107
|
+
`Coordinator → "${card.name}Coordinator/Service", InformationHolder → 도메인 명사 단독, Interfacer → "${card.name}View/Adapter".`,
|
|
108
|
+
tradeoffs: {
|
|
109
|
+
pros: [
|
|
110
|
+
"Wirfs-Brock stereotype과 이름이 일치해 협력 패턴 예측 가능",
|
|
111
|
+
"리뷰 시 책임 누수 판단이 쉬워짐",
|
|
112
|
+
],
|
|
113
|
+
cons: [
|
|
114
|
+
"stereotype 자체가 잘못 설정됐다면 잘못된 방향으로 재명명될 위험",
|
|
115
|
+
],
|
|
116
|
+
},
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
label: "협력자에게 책임 이전 후 클래스 삭제",
|
|
120
|
+
summary: `이 클래스가 *얇은 위임 계층*에 그친다면, 책임을 진짜 소유자(데이터를 가진 객체)에게 옮기고 클래스 자체를 제거한다.`,
|
|
121
|
+
tradeoffs: {
|
|
122
|
+
pros: [
|
|
123
|
+
"객체 수 감소 + Tell-Don't-Ask 강화",
|
|
124
|
+
"god-folder 안티패턴 회피",
|
|
125
|
+
],
|
|
126
|
+
cons: [
|
|
127
|
+
"협력자가 비대해질 위험 (다음 라운드에서 god-object 가능성)",
|
|
128
|
+
],
|
|
129
|
+
},
|
|
130
|
+
},
|
|
131
|
+
],
|
|
132
|
+
}));
|
|
133
|
+
}
|
|
134
|
+
return out;
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=vagueName.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vagueName.js","sourceRoot":"","sources":["../../src/validate/vagueName.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { assertHasMultipleRemedies } from "./findings.js";
|
|
2
|
+
// 검증/유효성 책임이 여러 stereotype에 분산되어 있으면 경고한다.
|
|
3
|
+
// 우아한테크코스 racing-car 미션에서 가장 흔하게 학생들이 헷갈리는 주제.
|
|
4
|
+
//
|
|
5
|
+
// 권장 3분류:
|
|
6
|
+
// - UI 형식 검증 (빈 문자열, 숫자 아님) → Interfacer
|
|
7
|
+
// - 사용자 입력 정책 (재입력 흐름) → Coordinator
|
|
8
|
+
// - 도메인 무결성 invariant (길이/중복/범위) → InformationHolder / Structurer 의 init
|
|
9
|
+
const VALIDATION_RE = /(검증|유효성|확인|검사|validate|valid|check|verify)/i;
|
|
10
|
+
function hasValidationResponsibility(card) {
|
|
11
|
+
const all = [...card.responsibilities.knowing, ...card.responsibilities.doing];
|
|
12
|
+
return all.some((r) => VALIDATION_RE.test(r));
|
|
13
|
+
}
|
|
14
|
+
function tokenize(text) {
|
|
15
|
+
return new Set(text
|
|
16
|
+
.toLowerCase()
|
|
17
|
+
.replace(/[()\[\]{}.,;:!?]/g, " ")
|
|
18
|
+
.split(/\s+/)
|
|
19
|
+
.filter((t) => t.length > 1));
|
|
20
|
+
}
|
|
21
|
+
function sharedDomainTokens(a, b) {
|
|
22
|
+
const at = tokenize([...a.responsibilities.knowing, ...a.responsibilities.doing].join(" "));
|
|
23
|
+
const bt = tokenize([...b.responsibilities.knowing, ...b.responsibilities.doing].join(" "));
|
|
24
|
+
const out = [];
|
|
25
|
+
for (const t of at)
|
|
26
|
+
if (bt.has(t))
|
|
27
|
+
out.push(t);
|
|
28
|
+
return out;
|
|
29
|
+
}
|
|
30
|
+
export function checkValidationLocation(design) {
|
|
31
|
+
const validators = design.classes.filter(hasValidationResponsibility);
|
|
32
|
+
if (validators.length < 2)
|
|
33
|
+
return [];
|
|
34
|
+
const out = [];
|
|
35
|
+
const seen = new Set();
|
|
36
|
+
for (let i = 0; i < validators.length; i++) {
|
|
37
|
+
for (let j = i + 1; j < validators.length; j++) {
|
|
38
|
+
const a = validators[i];
|
|
39
|
+
const b = validators[j];
|
|
40
|
+
const shared = sharedDomainTokens(a, b).filter((t) => !VALIDATION_RE.test(t));
|
|
41
|
+
if (shared.length < 2)
|
|
42
|
+
continue; // 같은 도메인 개념 공유가 약하면 분산이 아님
|
|
43
|
+
// 두 카드의 stereotype 조합으로 분산 패턴 판정
|
|
44
|
+
const stPair = [a.stereotype, b.stereotype].sort().join("+");
|
|
45
|
+
// 같은 stereotype이면 중복일 수 있으나 다른 stereotype이면 분산
|
|
46
|
+
if (a.stereotype === b.stereotype)
|
|
47
|
+
continue;
|
|
48
|
+
const key = `${a.id}+${b.id}`;
|
|
49
|
+
if (seen.has(key))
|
|
50
|
+
continue;
|
|
51
|
+
seen.add(key);
|
|
52
|
+
out.push(assertHasMultipleRemedies({
|
|
53
|
+
rule_id: "validation-misplacement",
|
|
54
|
+
severity: "warn",
|
|
55
|
+
target: { kind: "class", id: a.id },
|
|
56
|
+
message: `${a.name}(${a.stereotype})과 ${b.name}(${b.stereotype})이 같은 도메인 개념(${shared
|
|
57
|
+
.slice(0, 3)
|
|
58
|
+
.join(", ")})의 검증을 양쪽에서 수행합니다. ` +
|
|
59
|
+
`검증 책임이 분산되어 있어 변경 시 양쪽 모두 수정해야 할 위험이 있습니다.`,
|
|
60
|
+
evidence: {
|
|
61
|
+
paired_with: b.name,
|
|
62
|
+
paired_stereotype: b.stereotype,
|
|
63
|
+
shared_concepts: shared,
|
|
64
|
+
stereotype_pair: stPair,
|
|
65
|
+
guideline: "권장 3분류 — UI 형식: Interfacer / 입력 정책: Coordinator / 도메인 invariant: InformationHolder·Structurer init",
|
|
66
|
+
},
|
|
67
|
+
remedies: [
|
|
68
|
+
{
|
|
69
|
+
label: "도메인 invariant를 InformationHolder/Structurer init으로 통합",
|
|
70
|
+
summary: `검증의 *최종 진실*을 도메인 객체에 두고, 외부 검증은 제거한다. ` +
|
|
71
|
+
`호출 측은 도메인 생성 시점에 require/init으로 보호받는다.`,
|
|
72
|
+
tradeoffs: {
|
|
73
|
+
pros: [
|
|
74
|
+
"검증 위치가 단일 (이중 검증 제거)",
|
|
75
|
+
"도메인 진입점이 곧 검증 경계",
|
|
76
|
+
"리뷰어 다수가 권장한 표준 패턴",
|
|
77
|
+
],
|
|
78
|
+
cons: [
|
|
79
|
+
"도메인 init이 무거워질 수 있음",
|
|
80
|
+
"재입력 흐름과 도메인 예외를 호출 측이 어떻게 처리할지 결정 필요",
|
|
81
|
+
],
|
|
82
|
+
},
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
label: "Interfacer는 형식만, 도메인은 무결성만 (책임 분할)",
|
|
86
|
+
summary: `${a.name}/${b.name} 중 하나는 UI 형식 검증(빈 문자열, 숫자 아님)만, ` +
|
|
87
|
+
`다른 하나는 도메인 invariant(길이/중복/범위)만 갖도록 책임을 갈라낸다. ` +
|
|
88
|
+
`같은 토큰을 다루더라도 *검증의 종류*가 다르면 분산이 아님.`,
|
|
89
|
+
tradeoffs: {
|
|
90
|
+
pros: [
|
|
91
|
+
"각 stereotype에 맞는 검증만 남음",
|
|
92
|
+
"Interfacer 변경(UI 형식 변경)이 도메인에 영향 없음",
|
|
93
|
+
],
|
|
94
|
+
cons: [
|
|
95
|
+
"같은 입력값이 두 단계를 거치므로 호출 흐름이 복잡해짐",
|
|
96
|
+
"어디까지가 \"형식\"이고 어디부터가 \"무결성\"인지 팀 합의 필요",
|
|
97
|
+
],
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
label: "Coordinator가 재입력 흐름만 담당하도록 분리",
|
|
102
|
+
summary: `Coordinator는 \"검증 실패 시 재입력\" 같은 사용자 입력 정책만 갖고, ` +
|
|
103
|
+
`실제 검증 로직은 Interfacer(형식) 또는 도메인(무결성)이 담당한다.`,
|
|
104
|
+
tradeoffs: {
|
|
105
|
+
pros: [
|
|
106
|
+
"Coordinator가 검증 규칙을 *알지 않게* 됨",
|
|
107
|
+
"흐름 변경(재입력 vs 종료)이 검증 로직 변경과 분리됨",
|
|
108
|
+
],
|
|
109
|
+
cons: [
|
|
110
|
+
"단순 미션에서는 과한 분리일 수 있음",
|
|
111
|
+
],
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
],
|
|
115
|
+
}));
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return out;
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=validationLocation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validationLocation.js","sourceRoot":"","sources":["../../src/validate/validationLocation.ts"],"names":[],"mappings":"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"}
|