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,119 @@
|
|
|
1
|
+
import { assertHasMultipleRemedies } from "./findings.js";
|
|
2
|
+
// "빈 객체 + 외부 채우기" 안티패턴 — invariant 시간차.
|
|
3
|
+
// 대표 사례: val result = WinningResult(); lottos.forEach { result.add(rank) }
|
|
4
|
+
// 생성 시점엔 *불완전*, 사용 시점엔 *완전* — Tell-Don't-Ask 위반.
|
|
5
|
+
// woowacourse/kotlin-lotto PR #14 (@malibinYun)에서 정확히 이 패턴 지적.
|
|
6
|
+
const MUTATION_VERBS = [
|
|
7
|
+
// 한국어 동사 어간
|
|
8
|
+
"추가",
|
|
9
|
+
"누적",
|
|
10
|
+
"채우",
|
|
11
|
+
"세팅",
|
|
12
|
+
"등록",
|
|
13
|
+
"담",
|
|
14
|
+
"모으",
|
|
15
|
+
"쌓",
|
|
16
|
+
// 영어 동사
|
|
17
|
+
"add",
|
|
18
|
+
"append",
|
|
19
|
+
"put",
|
|
20
|
+
"set",
|
|
21
|
+
"record",
|
|
22
|
+
"register",
|
|
23
|
+
"collect",
|
|
24
|
+
"accumulate",
|
|
25
|
+
];
|
|
26
|
+
function matchedVerbs(text) {
|
|
27
|
+
const lower = text.toLowerCase();
|
|
28
|
+
return MUTATION_VERBS.filter((v) => lower.includes(v.toLowerCase()));
|
|
29
|
+
}
|
|
30
|
+
export function checkEmptyObjectFill(design) {
|
|
31
|
+
const out = [];
|
|
32
|
+
for (const card of design.classes) {
|
|
33
|
+
if (card.stereotype !== "InformationHolder")
|
|
34
|
+
continue;
|
|
35
|
+
if (card.responsibilities.knowing.length !== 0)
|
|
36
|
+
continue;
|
|
37
|
+
const doings = card.responsibilities.doing;
|
|
38
|
+
if (doings.length === 0)
|
|
39
|
+
continue;
|
|
40
|
+
const perDoingMatches = doings.map((d) => matchedVerbs(d));
|
|
41
|
+
const allMutation = perDoingMatches.every((m) => m.length > 0);
|
|
42
|
+
if (!allMutation)
|
|
43
|
+
continue;
|
|
44
|
+
const matchedSet = new Set();
|
|
45
|
+
for (const m of perDoingMatches)
|
|
46
|
+
for (const v of m)
|
|
47
|
+
matchedSet.add(v);
|
|
48
|
+
out.push(assertHasMultipleRemedies({
|
|
49
|
+
rule_id: "empty-object-external-fill",
|
|
50
|
+
severity: "warn",
|
|
51
|
+
target: { kind: "class", id: card.id },
|
|
52
|
+
message: `${card.name}은(는) InformationHolder인데 knowing이 비어 있고 doing이 모두 *외부에서 채우는* 동사로만 ` +
|
|
53
|
+
`구성되어 있습니다. *빈 껍데기 + 외부 조립* 패턴은 invariant 시간차(생성 시점엔 불완전, 사용 시점엔 완전)를 만듭니다.`,
|
|
54
|
+
evidence: {
|
|
55
|
+
stereotype: card.stereotype,
|
|
56
|
+
knowing_count: 0,
|
|
57
|
+
doing_count: doings.length,
|
|
58
|
+
mutation_verbs_matched: [...matchedSet],
|
|
59
|
+
example_doing: doings[0],
|
|
60
|
+
guideline: "@malibinYun (lotto PR #14): \"빈 껍데기의 WinningResult를 만들어서 값을 채우기보다, " +
|
|
61
|
+
"WinningResult를 직접 만들어서 반환하는 것은 어떨까요?\" — " +
|
|
62
|
+
"빈 객체 + 외부 채우기 = invariant 시간차. Tell-Don't-Ask 위반.",
|
|
63
|
+
},
|
|
64
|
+
remedies: [
|
|
65
|
+
{
|
|
66
|
+
label: "팩토리/부생성자로 *완성된* 객체 반환",
|
|
67
|
+
summary: `외부 루프에서 add를 반복하는 대신, 입력 컬렉션을 받아 한 번에 채우는 팩토리(또는 부생성자)로 ` +
|
|
68
|
+
`생성 시점에 invariant를 즉시 충족시킨다. ` +
|
|
69
|
+
`예: ${card.name}(items.map { it.toRank() }) 또는 ${card.name}.from(items, criteria).`,
|
|
70
|
+
tradeoffs: {
|
|
71
|
+
pros: [
|
|
72
|
+
"생성 시점에 invariant 즉시 충족 (불완전 상태가 외부에 노출되지 않음)",
|
|
73
|
+
"호출자가 add 호출 순서/누락을 신경 쓸 필요 없음",
|
|
74
|
+
"Tell-Don't-Ask: 호출자는 데이터만 넘기고 채우는 책임은 객체 내부에 위치",
|
|
75
|
+
],
|
|
76
|
+
cons: [
|
|
77
|
+
"스트리밍·점진 누적이 정당한 도메인에는 부적합",
|
|
78
|
+
"팩토리 시그니처가 입력 컬렉션 타입에 결합됨",
|
|
79
|
+
],
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
label: "Builder + 완성품 *타입 분리*",
|
|
84
|
+
summary: `조립 중 객체와 완성된 객체를 *다른 타입*으로 나눈다. ` +
|
|
85
|
+
`${card.name}Builder(가변, add 가능) → .build() → ${card.name}(불변, invariant 검증 완료). ` +
|
|
86
|
+
`호출부는 빌더만 만지고 도메인 코드는 완성품만 본다.`,
|
|
87
|
+
tradeoffs: {
|
|
88
|
+
pros: [
|
|
89
|
+
"조립 중/완성된 객체가 *타입으로 구분*되어 시간차 위반이 컴파일 단계에서 차단",
|
|
90
|
+
"다단계 조건부 조립을 자연스럽게 표현할 수 있음",
|
|
91
|
+
],
|
|
92
|
+
cons: [
|
|
93
|
+
"객체 수가 1개 늘어 초기 학습 비용 증가",
|
|
94
|
+
"단순한 컬렉션 매핑 수준의 도메인에는 과추상화",
|
|
95
|
+
],
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
label: "현 패턴 유지 + 사용 시점 invariant 검증",
|
|
100
|
+
summary: `외부 채우기 흐름을 유지하되, 값을 읽는 메서드 진입부에서 *내용물이 채워졌는지* require로 ` +
|
|
101
|
+
`명시한다. 이는 시간차 invariant를 *받아들이는* 선택임을 코드에 남겨두는 것.`,
|
|
102
|
+
tradeoffs: {
|
|
103
|
+
pros: [
|
|
104
|
+
"기존 호출 구조 변경 없음 (호환성 최대)",
|
|
105
|
+
"외부에서 점진 누적이 진짜 필요한 도메인에서는 자연스러움",
|
|
106
|
+
],
|
|
107
|
+
cons: [
|
|
108
|
+
"*불완전 객체*가 코드베이스에 떠다님 — 빈 상태에서 메서드 호출 시 런타임 폭발",
|
|
109
|
+
"테스트 fixture가 *조립 절차*를 매번 재현해야 해 testability 저하",
|
|
110
|
+
"조영호 「객체지향의 사실과 오해」: 객체는 *항상 유효한 상태*로 살아 있어야 한다는 원칙과 충돌",
|
|
111
|
+
],
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
],
|
|
115
|
+
}));
|
|
116
|
+
}
|
|
117
|
+
return out;
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=emptyObjectFill.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emptyObjectFill.js","sourceRoot":"","sources":["../../src/validate/emptyObjectFill.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export type Severity = "info" | "warn" | "error";
|
|
2
|
+
export interface Remedy {
|
|
3
|
+
label: string;
|
|
4
|
+
summary: string;
|
|
5
|
+
tradeoffs: {
|
|
6
|
+
pros: string[];
|
|
7
|
+
cons: string[];
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
export interface Finding {
|
|
11
|
+
rule_id: string;
|
|
12
|
+
severity: Severity;
|
|
13
|
+
target: {
|
|
14
|
+
kind: "class" | "collaboration" | "design";
|
|
15
|
+
id: string;
|
|
16
|
+
};
|
|
17
|
+
message: string;
|
|
18
|
+
evidence: Record<string, unknown>;
|
|
19
|
+
remedies: Remedy[];
|
|
20
|
+
}
|
|
21
|
+
export declare function severityAtLeast(s: Severity, min: Severity): boolean;
|
|
22
|
+
export declare function assertHasMultipleRemedies(f: Finding): Finding;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
const SEVERITY_RANK = { info: 0, warn: 1, error: 2 };
|
|
2
|
+
export function severityAtLeast(s, min) {
|
|
3
|
+
return SEVERITY_RANK[s] >= SEVERITY_RANK[min];
|
|
4
|
+
}
|
|
5
|
+
export function assertHasMultipleRemedies(f) {
|
|
6
|
+
if (f.remedies.length < 2) {
|
|
7
|
+
throw new Error(`Rule ${f.rule_id} produced a finding with fewer than 2 remedies. ` +
|
|
8
|
+
`Oh-My-OOP contract: every finding must offer at least 2 alternative remedies.`);
|
|
9
|
+
}
|
|
10
|
+
return f;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=findings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"findings.js","sourceRoot":"","sources":["../../src/validate/findings.ts"],"names":[],"mappings":"AAiBA,MAAM,aAAa,GAA6B,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;AAE/E,MAAM,UAAU,eAAe,CAAC,CAAW,EAAE,GAAa;IACxD,OAAO,aAAa,CAAC,CAAC,CAAC,IAAI,aAAa,CAAC,GAAG,CAAC,CAAC;AAChD,CAAC;AAED,MAAM,UAAU,yBAAyB,CAAC,CAAU;IAClD,IAAI,CAAC,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CACb,QAAQ,CAAC,CAAC,OAAO,kDAAkD;YACjE,+EAA+E,CAClF,CAAC;IACJ,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { assertHasMultipleRemedies } from "./findings.js";
|
|
2
|
+
// 한 가지 일을 *짧은 동사 함수 다수*로 쪼개는 안티패턴.
|
|
3
|
+
// 대표 사례: WinningDiscriminator init을 compute/extract/build/verify/format/trim 같은
|
|
4
|
+
// *도메인 명사 없는 짧은 동사*로 분해 — 의미 없는 단계 노출.
|
|
5
|
+
// 근거: lotto 일반 패턴 (MCP_STRUCTURE.md §5) — "함수를 *분리*하는 것이지 *분해*하는 것이 아니다" (@krrong 류 코멘트).
|
|
6
|
+
const SHORT_KOREAN_VERB = /^[가-힣]{1,5}(다|기|하기|함|이)?$/;
|
|
7
|
+
const SHORT_KOREAN_NOUN = /^[가-힣]{2,4}$/;
|
|
8
|
+
const SHORT_ENGLISH_VERB = /^[a-zA-Z]{2,10}$/;
|
|
9
|
+
function looksLikeShortStep(doing) {
|
|
10
|
+
const t = doing.trim();
|
|
11
|
+
if (t.length === 0)
|
|
12
|
+
return true; // 빈 책임도 결국 같은 시그널
|
|
13
|
+
if (t.length > 14)
|
|
14
|
+
return false; // 충분히 길면 도메인 어휘 동반 가능
|
|
15
|
+
if (SHORT_KOREAN_VERB.test(t))
|
|
16
|
+
return true;
|
|
17
|
+
if (SHORT_KOREAN_NOUN.test(t))
|
|
18
|
+
return true;
|
|
19
|
+
if (SHORT_ENGLISH_VERB.test(t))
|
|
20
|
+
return true;
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
function hasDomainNoun(doing) {
|
|
24
|
+
const t = doing.trim();
|
|
25
|
+
// 길이가 충분히 길고 공백/조사 포함이면 도메인 어휘 가능성이 큼.
|
|
26
|
+
if (t.length > 14)
|
|
27
|
+
return true;
|
|
28
|
+
// 명백한 도메인 명사 토큰 — 영어 PascalCase 단어, 한국어 4글자 이상 명사 추정
|
|
29
|
+
if (/[A-Z][a-z]+[A-Z]/.test(t))
|
|
30
|
+
return true; // CamelCase
|
|
31
|
+
if (/[가-힣]{5,}/.test(t))
|
|
32
|
+
return true;
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
export function checkFunctionDecompositionExcess(design) {
|
|
36
|
+
const out = [];
|
|
37
|
+
for (const card of design.classes) {
|
|
38
|
+
// Interfacer는 어댑터로서 짧은 메서드 다수가 자연스러움 — 스킵.
|
|
39
|
+
if (card.stereotype === "Interfacer")
|
|
40
|
+
continue;
|
|
41
|
+
const doing = card.responsibilities.doing;
|
|
42
|
+
if (doing.length < 4)
|
|
43
|
+
continue;
|
|
44
|
+
const shortSteps = doing.filter((d) => looksLikeShortStep(d));
|
|
45
|
+
const allShort = shortSteps.length === doing.length;
|
|
46
|
+
if (!allShort)
|
|
47
|
+
continue;
|
|
48
|
+
const anyDomainNoun = doing.some((d) => hasDomainNoun(d));
|
|
49
|
+
if (anyDomainNoun)
|
|
50
|
+
continue;
|
|
51
|
+
out.push(assertHasMultipleRemedies({
|
|
52
|
+
rule_id: "function-decomposition-excess",
|
|
53
|
+
severity: "info",
|
|
54
|
+
target: { kind: "class", id: card.id },
|
|
55
|
+
message: `${card.name}의 doing 책임이 ${doing.length}개로 *짧은 동사*에 머물러 있고, 도메인 명사가 보이지 않습니다. ` +
|
|
56
|
+
`한 가지 일을 의미 없는 단계들로 *분해*했을 가능성이 있습니다. ` +
|
|
57
|
+
`함수는 *분리*되어야 하지 *분해*되어선 안 됩니다 — 각 조각이 자기 이름값을 해야 합니다.`,
|
|
58
|
+
evidence: {
|
|
59
|
+
doing_count: doing.length,
|
|
60
|
+
short_step_samples: doing.slice(0, 4),
|
|
61
|
+
guideline: "lotto 일반 가르침: \"*함수를 분리하는 것이지 분해하는 것이 아니다*\". " +
|
|
62
|
+
"한 동작을 6개 헬퍼로 쪼개도 각 헬퍼가 도메인을 표현하지 않으면 *의미가 한 곳에 흩어지기만* 한다.",
|
|
63
|
+
},
|
|
64
|
+
remedies: [
|
|
65
|
+
{
|
|
66
|
+
label: "도메인 어휘로 *재명명* — 단계가 아니라 의도",
|
|
67
|
+
summary: `각 doing을 *무엇을 하는가*가 아니라 *왜 하는가*로 다시 이름 짓는다. ` +
|
|
68
|
+
`예: extract → \"당첨 번호 추출\", verify → \"중복 없음 보장\". ` +
|
|
69
|
+
`이름이 바뀌면 분리가 정당해지고, 정당화되지 않는 조각은 합쳐진다.`,
|
|
70
|
+
tradeoffs: {
|
|
71
|
+
pros: [
|
|
72
|
+
"각 조각이 *왜 존재하는지* 코드만 봐도 드러남",
|
|
73
|
+
"재명명 과정에서 *합쳐야 할 조각*이 자연스럽게 식별됨",
|
|
74
|
+
"리뷰어가 \"이 단계는 왜 있죠?\"를 물을 일이 줄어듦",
|
|
75
|
+
],
|
|
76
|
+
cons: [
|
|
77
|
+
"이름 자체가 길어져 라인 폭이 늘 수 있음",
|
|
78
|
+
"기존 호출자의 메서드명 의존이 깨질 수 있음 (검색/리네임 비용)",
|
|
79
|
+
],
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
label: "단계 *재흡수* — 한 메서드 안으로 합치기",
|
|
84
|
+
summary: `이름값 못 하는 조각들을 한 도메인 메서드 안의 *지역 변수/표현식*으로 합친다. ` +
|
|
85
|
+
`여러 헬퍼가 단 한 곳에서만 불린다면, 헬퍼는 *변수 하나*만큼의 가치도 못 한다.`,
|
|
86
|
+
tradeoffs: {
|
|
87
|
+
pros: [
|
|
88
|
+
"*단일 사용 헬퍼* 제거로 호출 그래프 단순화",
|
|
89
|
+
"맥락이 한 자리에 모여 *읽기 흐름*이 끊기지 않음",
|
|
90
|
+
"테스트가 *행위 단위*로 작성되어 단계별 결합 감소",
|
|
91
|
+
],
|
|
92
|
+
cons: [
|
|
93
|
+
"메서드 한 개의 라인 수가 증가",
|
|
94
|
+
"조각마다 단위 테스트하던 패턴이 깨짐 — 더 큰 단위 테스트가 필요",
|
|
95
|
+
],
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
label: "*진짜 협력자*로 단계를 객체화",
|
|
100
|
+
summary: `조각 중 *2개 이상*이 한 도메인 개념(예: NumberExtractor, DuplicationGuard)을 함께 ` +
|
|
101
|
+
`표현한다면 새 ServiceProvider로 빼서 ${card.name}의 협력자가 되게 한다. ` +
|
|
102
|
+
`*함수 분해*가 아니라 *객체 분리*로 승격.`,
|
|
103
|
+
tradeoffs: {
|
|
104
|
+
pros: [
|
|
105
|
+
"함수 다수가 *진짜 책임*을 가진 객체로 승격",
|
|
106
|
+
"테스트 단위가 *객체 경계*로 다시 정렬됨",
|
|
107
|
+
"OCP에 가까워짐 — 새 정책 추가가 새 객체로 가능",
|
|
108
|
+
],
|
|
109
|
+
cons: [
|
|
110
|
+
"객체 수 증가 — 통증이 적다면 과설계",
|
|
111
|
+
"협력 그래프가 복잡해져 *호출 흐름 추적* 비용 증가",
|
|
112
|
+
],
|
|
113
|
+
},
|
|
114
|
+
},
|
|
115
|
+
],
|
|
116
|
+
}));
|
|
117
|
+
}
|
|
118
|
+
return out;
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=functionDecompositionExcess.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"functionDecompositionExcess.js","sourceRoot":"","sources":["../../src/validate/functionDecompositionExcess.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,yBAAyB,EAAE,MAAM,eAAe,CAAC;AAE1D,mCAAmC;AACnC,gFAAgF;AAChF,uCAAuC;AACvC,0FAA0F;AAE1F,MAAM,iBAAiB,GAAG,2BAA2B,CAAC;AACtD,MAAM,iBAAiB,GAAG,cAAc,CAAC;AACzC,MAAM,kBAAkB,GAAG,kBAAkB,CAAC;AAE9C,SAAS,kBAAkB,CAAC,KAAa;IACvC,MAAM,CAAC,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IACvB,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC,CAAC,kBAAkB;IACnD,IAAI,CAAC,CAAC,MAAM,GAAG,EAAE;QAAE,OAAO,KAAK,CAAC,CAAC,sBAAsB;IACvD,IAAI,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IAC3C,IAAI,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IAC3C,IAAI,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IAC5C,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,aAAa,CAAC,KAAa;IAClC,MAAM,CAAC,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IACvB,uCAAuC;IACvC,IAAI,CAAC,CAAC,MAAM,GAAG,EAAE;QAAE,OAAO,IAAI,CAAC;IAC/B,qDAAqD;IACrD,IAAI,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC,CAAC,YAAY;IACzD,IAAI,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IACrC,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,gCAAgC,CAAC,MAAc;IAC7D,MAAM,GAAG,GAAc,EAAE,CAAC;IAE1B,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QAClC,2CAA2C;QAC3C,IAAI,IAAI,CAAC,UAAU,KAAK,YAAY;YAAE,SAAS;QAE/C,MAAM,KAAK,GAAG,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC;QAC1C,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;YAAE,SAAS;QAE/B,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9D,MAAM,QAAQ,GAAG,UAAU,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,CAAC;QACpD,IAAI,CAAC,QAAQ;YAAE,SAAS;QAExB,MAAM,aAAa,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1D,IAAI,aAAa;YAAE,SAAS;QAE5B,GAAG,CAAC,IAAI,CACN,yBAAyB,CAAC;YACxB,OAAO,EAAE,+BAA+B;YACxC,QAAQ,EAAE,MAAM;YAChB,MAAM,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE;YACtC,OAAO,EACL,GAAG,IAAI,CAAC,IAAI,eAAe,KAAK,CAAC,MAAM,wCAAwC;gBAC/E,uCAAuC;gBACvC,sDAAsD;YACxD,QAAQ,EAAE;gBACR,WAAW,EAAE,KAAK,CAAC,MAAM;gBACzB,kBAAkB,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;gBACrC,SAAS,EACP,gDAAgD;oBAChD,2DAA2D;aAC9D;YACD,QAAQ,EAAE;gBACR;oBACE,KAAK,EAAE,4BAA4B;oBACnC,OAAO,EACL,8CAA8C;wBAC9C,oDAAoD;wBACpD,uCAAuC;oBACzC,SAAS,EAAE;wBACT,IAAI,EAAE;4BACJ,4BAA4B;4BAC5B,gCAAgC;4BAChC,iCAAiC;yBAClC;wBACD,IAAI,EAAE;4BACJ,yBAAyB;4BACzB,sCAAsC;yBACvC;qBACF;iBACF;gBACD;oBACE,KAAK,EAAE,0BAA0B;oBACjC,OAAO,EACL,gDAAgD;wBAChD,gDAAgD;oBAClD,SAAS,EAAE;wBACT,IAAI,EAAE;4BACJ,2BAA2B;4BAC3B,8BAA8B;4BAC9B,8BAA8B;yBAC/B;wBACD,IAAI,EAAE;4BACJ,mBAAmB;4BACnB,uCAAuC;yBACxC;qBACF;iBACF;gBACD;oBACE,KAAK,EAAE,mBAAmB;oBAC1B,OAAO,EACL,mEAAmE;wBACnE,+BAA+B,IAAI,CAAC,IAAI,gBAAgB;wBACxD,2BAA2B;oBAC7B,SAAS,EAAE;wBACT,IAAI,EAAE;4BACJ,2BAA2B;4BAC3B,yBAAyB;4BACzB,+BAA+B;yBAChC;wBACD,IAAI,EAAE;4BACJ,uBAAuB;4BACvB,+BAA+B;yBAChC;qBACF;iBACF;aACF;SACF,CAAC,CACH,CAAC;IACJ,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { assertHasMultipleRemedies } from "./findings.js";
|
|
2
|
+
// "객체는 메서드 + 멤버 둘 다" — @ghojeong (PR #128)
|
|
3
|
+
// 멤버(knowing) 없이 행위(doing) 하나만 있는 클래스는 사실상 함수.
|
|
4
|
+
// "judge() 함수만 가진 Winner 클래스"가 대표 사례.
|
|
5
|
+
export function checkFunctionNotObject(design) {
|
|
6
|
+
const out = [];
|
|
7
|
+
for (const card of design.classes) {
|
|
8
|
+
const knowingCount = card.responsibilities.knowing.length;
|
|
9
|
+
const doingCount = card.responsibilities.doing.length;
|
|
10
|
+
// 멤버 0 + 행위 1개 → 함수에 가까움
|
|
11
|
+
// 단, Interfacer는 외부 시스템과의 어댑터로 knowing이 0일 수 있어 예외
|
|
12
|
+
if (card.stereotype === "Interfacer")
|
|
13
|
+
continue;
|
|
14
|
+
if (knowingCount > 0)
|
|
15
|
+
continue;
|
|
16
|
+
if (doingCount !== 1)
|
|
17
|
+
continue;
|
|
18
|
+
out.push(assertHasMultipleRemedies({
|
|
19
|
+
rule_id: "function-not-object",
|
|
20
|
+
severity: "info",
|
|
21
|
+
target: { kind: "class", id: card.id },
|
|
22
|
+
message: `${card.name}은(는) knowing(멤버)이 없고 doing이 1개뿐이라 사실상 *함수*에 가깝습니다. ` +
|
|
23
|
+
`객체는 메서드와 멤버 둘 다로 구성됩니다.`,
|
|
24
|
+
evidence: {
|
|
25
|
+
knowing_count: knowingCount,
|
|
26
|
+
doing_count: doingCount,
|
|
27
|
+
stereotype: card.stereotype,
|
|
28
|
+
doing_text: card.responsibilities.doing[0],
|
|
29
|
+
guideline: "@ghojeong (PR #128): \"객체는 메서드 뿐만 아니라 멤버로도 구성된다는 사실을 잊지 말아주세요.\"",
|
|
30
|
+
},
|
|
31
|
+
remedies: [
|
|
32
|
+
{
|
|
33
|
+
label: "함수로 강등 (top-level 또는 object의 메서드)",
|
|
34
|
+
summary: `클래스로 둘 가치가 없다면 일반 함수 또는 object 안의 함수로 옮긴다. ` +
|
|
35
|
+
`호출자가 인스턴스화 부담에서 해방된다.`,
|
|
36
|
+
tradeoffs: {
|
|
37
|
+
pros: [
|
|
38
|
+
"객체 수 감소",
|
|
39
|
+
"호출 단순화 (인스턴스화 불필요)",
|
|
40
|
+
"분리의 정당화가 약한 클래스 제거",
|
|
41
|
+
],
|
|
42
|
+
cons: [
|
|
43
|
+
"나중에 상태가 추가될 가능성이 있다면 다시 클래스로 되돌리는 비용",
|
|
44
|
+
],
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
label: "데이터 소유 객체에 메서드로 흡수",
|
|
49
|
+
summary: `${card.responsibilities.doing[0]} 행위가 다루는 데이터의 소유자(예: 일급 컬렉션)에 ` +
|
|
50
|
+
`메서드로 옮긴다. Tell-Don't-Ask 강화.`,
|
|
51
|
+
tradeoffs: {
|
|
52
|
+
pros: [
|
|
53
|
+
"행위와 데이터가 한 곳에 (응집도 향상)",
|
|
54
|
+
"기존 호출자는 더 자연스러운 메시지 사용",
|
|
55
|
+
],
|
|
56
|
+
cons: [
|
|
57
|
+
"데이터 소유 객체가 비대해질 수 있음",
|
|
58
|
+
],
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
label: "멤버를 추가해 진짜 객체로 격상",
|
|
63
|
+
summary: `이 클래스가 *영구한 상태/정책*을 가져야 한다면 knowing을 추가한다. ` +
|
|
64
|
+
`예: ${card.name}이 정책 객체라면 정책 파라미터(임계값 등)를 멤버로.`,
|
|
65
|
+
tradeoffs: {
|
|
66
|
+
pros: [
|
|
67
|
+
"클래스로 둘 정당성이 생김",
|
|
68
|
+
"정책 변경 시 인스턴스만 교체",
|
|
69
|
+
],
|
|
70
|
+
cons: [
|
|
71
|
+
"knowing이 사실은 *외부 의존*에 불과하다면 부자연스러운 멤버화",
|
|
72
|
+
],
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
],
|
|
76
|
+
}));
|
|
77
|
+
}
|
|
78
|
+
return out;
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=functionNotObject.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"functionNotObject.js","sourceRoot":"","sources":["../../src/validate/functionNotObject.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,yBAAyB,EAAE,MAAM,eAAe,CAAC;AAE1D,2CAA2C;AAC3C,+CAA+C;AAC/C,sCAAsC;AAEtC,MAAM,UAAU,sBAAsB,CAAC,MAAc;IACnD,MAAM,GAAG,GAAc,EAAE,CAAC;IAE1B,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QAClC,MAAM,YAAY,GAAG,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,MAAM,CAAC;QAC1D,MAAM,UAAU,GAAG,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,MAAM,CAAC;QAEtD,yBAAyB;QACzB,mDAAmD;QACnD,IAAI,IAAI,CAAC,UAAU,KAAK,YAAY;YAAE,SAAS;QAC/C,IAAI,YAAY,GAAG,CAAC;YAAE,SAAS;QAC/B,IAAI,UAAU,KAAK,CAAC;YAAE,SAAS;QAE/B,GAAG,CAAC,IAAI,CACN,yBAAyB,CAAC;YACxB,OAAO,EAAE,qBAAqB;YAC9B,QAAQ,EAAE,MAAM;YAChB,MAAM,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE;YACtC,OAAO,EACL,GAAG,IAAI,CAAC,IAAI,qDAAqD;gBACjE,yBAAyB;YAC3B,QAAQ,EAAE;gBACR,aAAa,EAAE,YAAY;gBAC3B,WAAW,EAAE,UAAU;gBACvB,UAAU,EAAE,IAAI,CAAC,UAAU;gBAC3B,UAAU,EAAE,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,CAAC;gBAC1C,SAAS,EACP,kEAAkE;aACrE;YACD,QAAQ,EAAE;gBACR;oBACE,KAAK,EAAE,mCAAmC;oBAC1C,OAAO,EACL,6CAA6C;wBAC7C,uBAAuB;oBACzB,SAAS,EAAE;wBACT,IAAI,EAAE;4BACJ,SAAS;4BACT,oBAAoB;4BACpB,oBAAoB;yBACrB;wBACD,IAAI,EAAE;4BACJ,sCAAsC;yBACvC;qBACF;iBACF;gBACD;oBACE,KAAK,EAAE,oBAAoB;oBAC3B,OAAO,EACL,GAAG,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,CAAC,gCAAgC;wBACjE,8BAA8B;oBAChC,SAAS,EAAE;wBACT,IAAI,EAAE;4BACJ,wBAAwB;4BACxB,wBAAwB;yBACzB;wBACD,IAAI,EAAE;4BACJ,sBAAsB;yBACvB;qBACF;iBACF;gBACD;oBACE,KAAK,EAAE,mBAAmB;oBAC1B,OAAO,EACL,6CAA6C;wBAC7C,MAAM,IAAI,CAAC,IAAI,gCAAgC;oBACjD,SAAS,EAAE;wBACT,IAAI,EAAE;4BACJ,gBAAgB;4BAChB,kBAAkB;yBACnB;wBACD,IAAI,EAAE;4BACJ,wCAAwC;yBACzC;qBACF;iBACF;aACF;SACF,CAAC,CACH,CAAC;IACJ,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { assertHasMultipleRemedies } from "./findings.js";
|
|
2
|
+
export function checkGodObject(design, thresholds) {
|
|
3
|
+
const out = [];
|
|
4
|
+
for (const card of design.classes) {
|
|
5
|
+
const total = card.responsibilities.knowing.length + card.responsibilities.doing.length;
|
|
6
|
+
const tooManyResp = total > thresholds.responsibilities;
|
|
7
|
+
const tooManyCollab = card.collaborators.length > thresholds.collaborators;
|
|
8
|
+
if (!tooManyResp && !tooManyCollab)
|
|
9
|
+
continue;
|
|
10
|
+
out.push(assertHasMultipleRemedies({
|
|
11
|
+
rule_id: "god-object",
|
|
12
|
+
severity: "warn",
|
|
13
|
+
target: { kind: "class", id: card.id },
|
|
14
|
+
message: `${card.name}이(가) ${total}개의 책임, ${card.collaborators.length}명의 협력자를 가져 ` +
|
|
15
|
+
`(${tooManyResp ? "책임 과다" : ""}${tooManyResp && tooManyCollab ? " · " : ""}${tooManyCollab ? "협력자 과다" : ""}) ` +
|
|
16
|
+
`God Object 가능성이 있습니다.`,
|
|
17
|
+
evidence: {
|
|
18
|
+
responsibilities: total,
|
|
19
|
+
collaborators: card.collaborators.length,
|
|
20
|
+
thresholds,
|
|
21
|
+
guideline: "@ghojeong (woowacourse-kotlin-blackjack kimhm0728/72): \"해당 역할을 컴퓨터가 아니라 사람에게 시키려고 했을 때, 사람이 한 명 더 필요한가 아니면 같은 사람에게 시킬 수 있을까를 고민해보세요.\" — " +
|
|
22
|
+
"한 객체가 *여러 역할*을 가지면 사람 시뮬레이션 결과로 분리 후보. " +
|
|
23
|
+
"변경 이유가 *둘 이상의 축*에 모이면 god-object 의 시작이다.",
|
|
24
|
+
},
|
|
25
|
+
remedies: [
|
|
26
|
+
{
|
|
27
|
+
label: "doing 클러스터를 새 협력자로 추출",
|
|
28
|
+
summary: "가장 응집도 높은 doing 책임 묶음을 별개 ServiceProvider로 분리하고, " +
|
|
29
|
+
"현재 클래스는 그 협력자에게 위임한다.",
|
|
30
|
+
tradeoffs: {
|
|
31
|
+
pros: [
|
|
32
|
+
"각 클래스 책임이 명확해진다",
|
|
33
|
+
"테스트 단위가 작아진다",
|
|
34
|
+
"변경 영향 범위가 축소된다",
|
|
35
|
+
],
|
|
36
|
+
cons: [
|
|
37
|
+
"협력자 수가 1 증가하여 결합도 측면은 트레이드오프",
|
|
38
|
+
"추출 기준이 모호하면 인위적인 분리가 될 수 있음",
|
|
39
|
+
],
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
label: "knowing 클러스터를 값 객체(InformationHolder)로 추출",
|
|
44
|
+
summary: "강하게 묶인 knowing 책임을 새 InformationHolder로 옮기고, " +
|
|
45
|
+
"이 클래스는 그 값을 보유하도록 한다.",
|
|
46
|
+
tradeoffs: {
|
|
47
|
+
pros: [
|
|
48
|
+
"도메인 개념이 1급으로 드러난다",
|
|
49
|
+
"원시 타입 강박을 줄인다",
|
|
50
|
+
],
|
|
51
|
+
cons: [
|
|
52
|
+
"단순 위임이 늘어 표면적인 코드량이 증가",
|
|
53
|
+
"값 객체가 진짜 도메인 개념이 아니면 과한 추상화",
|
|
54
|
+
],
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
label: "Coordinator/Service 분리 (역할별 분할)",
|
|
59
|
+
summary: "흐름 조율(Coordinator)과 도메인 계산(ServiceProvider)을 다른 클래스로 분리한다.",
|
|
60
|
+
tradeoffs: {
|
|
61
|
+
pros: [
|
|
62
|
+
"Stereotype 혼합을 제거해 책임이 깔끔해짐",
|
|
63
|
+
"Tell-Don't-Ask 적용이 쉬워짐",
|
|
64
|
+
],
|
|
65
|
+
cons: [
|
|
66
|
+
"객체 수가 늘어 초기 학습 비용 증가",
|
|
67
|
+
"유스케이스가 단순하면 과설계가 될 수 있음",
|
|
68
|
+
],
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
],
|
|
72
|
+
}));
|
|
73
|
+
}
|
|
74
|
+
return out;
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=godObject.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"godObject.js","sourceRoot":"","sources":["../../src/validate/godObject.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,yBAAyB,EAAE,MAAM,eAAe,CAAC;AAE1D,MAAM,UAAU,cAAc,CAC5B,MAAc,EACd,UAA+D;IAE/D,MAAM,GAAG,GAAc,EAAE,CAAC;IAC1B,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QAClC,MAAM,KAAK,GACT,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,MAAM,CAAC;QAC5E,MAAM,WAAW,GAAG,KAAK,GAAG,UAAU,CAAC,gBAAgB,CAAC;QACxD,MAAM,aAAa,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,GAAG,UAAU,CAAC,aAAa,CAAC;QAC3E,IAAI,CAAC,WAAW,IAAI,CAAC,aAAa;YAAE,SAAS;QAE7C,GAAG,CAAC,IAAI,CACN,yBAAyB,CAAC;YACxB,OAAO,EAAE,YAAY;YACrB,QAAQ,EAAE,MAAM;YAChB,MAAM,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE;YACtC,OAAO,EACL,GAAG,IAAI,CAAC,IAAI,QAAQ,KAAK,UAAU,IAAI,CAAC,aAAa,CAAC,MAAM,aAAa;gBACzE,IAAI,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,GAAG,WAAW,IAAI,aAAa,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,IAAI;gBAC9G,uBAAuB;YACzB,QAAQ,EAAE;gBACR,gBAAgB,EAAE,KAAK;gBACvB,aAAa,EAAE,IAAI,CAAC,aAAa,CAAC,MAAM;gBACxC,UAAU;gBACV,SAAS,EACP,4IAA4I;oBAC5I,yCAAyC;oBACzC,0CAA0C;aAC7C;YACD,QAAQ,EAAE;gBACR;oBACE,KAAK,EAAE,uBAAuB;oBAC9B,OAAO,EACL,mDAAmD;wBACnD,uBAAuB;oBACzB,SAAS,EAAE;wBACT,IAAI,EAAE;4BACJ,iBAAiB;4BACjB,cAAc;4BACd,gBAAgB;yBACjB;wBACD,IAAI,EAAE;4BACJ,8BAA8B;4BAC9B,6BAA6B;yBAC9B;qBACF;iBACF;gBACD;oBACE,KAAK,EAAE,2CAA2C;oBAClD,OAAO,EACL,+CAA+C;wBAC/C,uBAAuB;oBACzB,SAAS,EAAE;wBACT,IAAI,EAAE;4BACJ,mBAAmB;4BACnB,eAAe;yBAChB;wBACD,IAAI,EAAE;4BACJ,wBAAwB;4BACxB,6BAA6B;yBAC9B;qBACF;iBACF;gBACD;oBACE,KAAK,EAAE,iCAAiC;oBACxC,OAAO,EACL,4DAA4D;oBAC9D,SAAS,EAAE;wBACT,IAAI,EAAE;4BACJ,6BAA6B;4BAC7B,wBAAwB;yBACzB;wBACD,IAAI,EAAE;4BACJ,sBAAsB;4BACtB,yBAAyB;yBAC1B;qBACF;iBACF;aACF;SACF,CAAC,CACH,CAAC;IACJ,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { assertHasMultipleRemedies } from "./findings.js";
|
|
2
|
+
// 계층 누수(presentation-in-domain): 도메인 stereotype(비-Interfacer)이 표현/출력 책임을 가짐.
|
|
3
|
+
// 예) InformationHolder가 자기 상태를 표시 문자열로 포맷(toString/getStatus류).
|
|
4
|
+
// 표현 형식 결정은 Interfacer(View)의 자리다 (Wirfs-Brock stereotype, 조영호).
|
|
5
|
+
// 도메인이 표시 문자열을 만들면 출력 형식이 바뀔 때 도메인이 오염된다.
|
|
6
|
+
//
|
|
7
|
+
// 주의: 설계 모델의 *책임 문구*에 대한 휴리스틱이다(코드 파싱 아님) → 권고(warn), 오탐 가능.
|
|
8
|
+
const PRESENTATION_RE = /(출력|화면|콘솔|포맷|렌더|문자열로\s*(표현|표시|변환|만든)|표시한다|toString|\bprint|\brender|\bformat|\bdisplay)/i;
|
|
9
|
+
export function checkPresentationInDomain(design) {
|
|
10
|
+
const out = [];
|
|
11
|
+
for (const card of design.classes) {
|
|
12
|
+
// 표현은 Interfacer의 정당한 책임 → 면제
|
|
13
|
+
if (card.stereotype === "Interfacer")
|
|
14
|
+
continue;
|
|
15
|
+
const offenders = card.responsibilities.doing.filter((d) => PRESENTATION_RE.test(d));
|
|
16
|
+
if (offenders.length === 0)
|
|
17
|
+
continue;
|
|
18
|
+
out.push(assertHasMultipleRemedies({
|
|
19
|
+
rule_id: "presentation-in-domain",
|
|
20
|
+
severity: "warn",
|
|
21
|
+
target: { kind: "class", id: card.id },
|
|
22
|
+
message: `${card.name}(${card.stereotype})이(가) 표현/출력 책임(${offenders
|
|
23
|
+
.map((o) => `"${o}"`)
|
|
24
|
+
.join(", ")})을 가집니다. ` +
|
|
25
|
+
`표현 형식 결정은 Interfacer(View)의 자리입니다 — 도메인 객체가 표시 문자열을 만들면 출력 형식 변경이 도메인을 오염시킵니다.`,
|
|
26
|
+
evidence: { stereotype: card.stereotype, offending_responsibilities: offenders },
|
|
27
|
+
remedies: [
|
|
28
|
+
{
|
|
29
|
+
label: "표현 책임을 Interfacer로 이전",
|
|
30
|
+
summary: "표시 형식 결정을 View/OutputView 같은 Interfacer로 옮기고, 도메인은 값/상태만 노출한다.",
|
|
31
|
+
tradeoffs: {
|
|
32
|
+
pros: ["출력 형식 변경이 도메인을 건드리지 않는다", "도메인이 순수해져 단위 테스트가 쉽다"],
|
|
33
|
+
cons: ["뷰가 도메인 값을 읽게 되어 약한 노출이 생긴다"],
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
label: "표시용 값 객체를 반환",
|
|
38
|
+
summary: "포맷된 문자열 대신 구조화된 표시용 값(예: 이름+위치)을 반환하고, 포맷은 호출측(뷰)이 결정한다.",
|
|
39
|
+
tradeoffs: {
|
|
40
|
+
pros: ["뷰가 도메인 내부가 아니라 명시적 계약에 의존한다", "도메인 내부 리팩터링에 강하다"],
|
|
41
|
+
cons: ["표시용 타입이 하나 늘어난다"],
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
label: "단순 케이스면 의도를 명시하고 유지",
|
|
46
|
+
summary: "출력 형식이 사소하고 변하지 않는다면 notes에 사유를 적고 유지한다.",
|
|
47
|
+
tradeoffs: {
|
|
48
|
+
pros: ["작은 미션에 실용적이다", "객체 수가 최소화된다"],
|
|
49
|
+
cons: ["형식 변경 시 도메인 수정이 필요하다", "stereotype 경계가 흐려진다"],
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
],
|
|
53
|
+
}));
|
|
54
|
+
}
|
|
55
|
+
return out;
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=presentationInDomain.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"presentationInDomain.js","sourceRoot":"","sources":["../../src/validate/presentationInDomain.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,yBAAyB,EAAE,MAAM,eAAe,CAAC;AAE1D,6EAA6E;AAC7E,gEAAgE;AAChE,iEAAiE;AACjE,0CAA0C;AAC1C,EAAE;AACF,6DAA6D;AAC7D,MAAM,eAAe,GACnB,0FAA0F,CAAC;AAE7F,MAAM,UAAU,yBAAyB,CAAC,MAAc;IACtD,MAAM,GAAG,GAAc,EAAE,CAAC;IAC1B,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QAClC,8BAA8B;QAC9B,IAAI,IAAI,CAAC,UAAU,KAAK,YAAY;YAAE,SAAS;QAC/C,MAAM,SAAS,GAAG,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QACrF,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;YAAE,SAAS;QACrC,GAAG,CAAC,IAAI,CACN,yBAAyB,CAAC;YACxB,OAAO,EAAE,wBAAwB;YACjC,QAAQ,EAAE,MAAM;YAChB,MAAM,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE;YACtC,OAAO,EACL,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,UAAU,kBAAkB,SAAS;iBACvD,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC;iBACpB,IAAI,CAAC,IAAI,CAAC,WAAW;gBACxB,gFAAgF;YAClF,QAAQ,EAAE,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,0BAA0B,EAAE,SAAS,EAAE;YAChF,QAAQ,EAAE;gBACR;oBACE,KAAK,EAAE,uBAAuB;oBAC9B,OAAO,EACL,gEAAgE;oBAClE,SAAS,EAAE;wBACT,IAAI,EAAE,CAAC,yBAAyB,EAAE,sBAAsB,CAAC;wBACzD,IAAI,EAAE,CAAC,4BAA4B,CAAC;qBACrC;iBACF;gBACD;oBACE,KAAK,EAAE,cAAc;oBACrB,OAAO,EACL,0DAA0D;oBAC5D,SAAS,EAAE;wBACT,IAAI,EAAE,CAAC,6BAA6B,EAAE,kBAAkB,CAAC;wBACzD,IAAI,EAAE,CAAC,iBAAiB,CAAC;qBAC1B;iBACF;gBACD;oBACE,KAAK,EAAE,qBAAqB;oBAC5B,OAAO,EAAE,0CAA0C;oBACnD,SAAS,EAAE;wBACT,IAAI,EAAE,CAAC,cAAc,EAAE,aAAa,CAAC;wBACrC,IAAI,EAAE,CAAC,sBAAsB,EAAE,qBAAqB,CAAC;qBACtD;iBACF;aACF;SACF,CAAC,CACH,CAAC;IACJ,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
|