@k2works/claude-code-booster 3.0.0 → 3.1.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/lib/assets/docs/article/functional-desgin-ppp/all/01-immutability-and-data-transformation.md +475 -0
- package/lib/assets/docs/article/functional-desgin-ppp/all/02-function-composition.md +519 -0
- package/lib/assets/docs/article/functional-desgin-ppp/all/03-polymorphism.md +537 -0
- package/lib/assets/docs/article/functional-desgin-ppp/all/04-data-validation.md +300 -0
- package/lib/assets/docs/article/functional-desgin-ppp/all/05-property-based-testing.md +320 -0
- package/lib/assets/docs/article/functional-desgin-ppp/all/06-tdd-and-functional.md +498 -0
- package/lib/assets/docs/article/functional-desgin-ppp/all/07-composite-pattern.md +298 -0
- package/lib/assets/docs/article/functional-desgin-ppp/all/08-decorator-pattern.md +291 -0
- package/lib/assets/docs/article/functional-desgin-ppp/all/09-adapter-pattern.md +336 -0
- package/lib/assets/docs/article/functional-desgin-ppp/all/10-strategy-pattern.md +303 -0
- package/lib/assets/docs/article/functional-desgin-ppp/all/11-command-pattern.md +286 -0
- package/lib/assets/docs/article/functional-desgin-ppp/all/12-visitor-pattern.md +322 -0
- package/lib/assets/docs/article/functional-desgin-ppp/all/13-abstract-factory-pattern.md +319 -0
- package/lib/assets/docs/article/functional-desgin-ppp/all/14-abstract-server-pattern.md +365 -0
- package/lib/assets/docs/article/functional-desgin-ppp/all/15-gossiping-bus-drivers.md +156 -0
- package/lib/assets/docs/article/functional-desgin-ppp/all/16-payroll-system.md +178 -0
- package/lib/assets/docs/article/functional-desgin-ppp/all/17-video-rental-system.md +312 -0
- package/lib/assets/docs/article/functional-desgin-ppp/all/18-concurrency-system.md +287 -0
- package/lib/assets/docs/article/functional-desgin-ppp/all/19-wa-tor-simulation.md +286 -0
- package/lib/assets/docs/article/functional-desgin-ppp/all/20-pattern-interactions.md +274 -0
- package/lib/assets/docs/article/functional-desgin-ppp/all/21-best-practices.md +294 -0
- package/lib/assets/docs/article/functional-desgin-ppp/all/22-oo-to-fp-migration.md +337 -0
- package/lib/assets/docs/article/functional-desgin-ppp/all/index.md +388 -0
- package/lib/assets/docs/article/functional-desgin-ppp/clojure/01-immutability-and-data-transformation.md +271 -0
- package/lib/assets/docs/article/functional-desgin-ppp/clojure/02-function-composition.md +380 -0
- package/lib/assets/docs/article/functional-desgin-ppp/clojure/03-polymorphism.md +384 -0
- package/lib/assets/docs/article/functional-desgin-ppp/clojure/04-clojure-spec.md +350 -0
- package/lib/assets/docs/article/functional-desgin-ppp/clojure/05-property-based-testing.md +352 -0
- package/lib/assets/docs/article/functional-desgin-ppp/clojure/06-tdd-in-functional.md +383 -0
- package/lib/assets/docs/article/functional-desgin-ppp/clojure/07-composite-pattern.md +529 -0
- package/lib/assets/docs/article/functional-desgin-ppp/clojure/08-decorator-pattern.md +395 -0
- package/lib/assets/docs/article/functional-desgin-ppp/clojure/09-adapter-pattern.md +399 -0
- package/lib/assets/docs/article/functional-desgin-ppp/clojure/10-strategy-pattern.md +485 -0
- package/lib/assets/docs/article/functional-desgin-ppp/clojure/11-command-pattern.md +566 -0
- package/lib/assets/docs/article/functional-desgin-ppp/clojure/12-visitor-pattern.md +567 -0
- package/lib/assets/docs/article/functional-desgin-ppp/clojure/13-abstract-factory-pattern.md +475 -0
- package/lib/assets/docs/article/functional-desgin-ppp/clojure/14-abstract-server-pattern.md +462 -0
- package/lib/assets/docs/article/functional-desgin-ppp/clojure/15-gossiping-bus-drivers.md +323 -0
- package/lib/assets/docs/article/functional-desgin-ppp/clojure/16-payroll-system.md +401 -0
- package/lib/assets/docs/article/functional-desgin-ppp/clojure/17-video-rental-system.md +450 -0
- package/lib/assets/docs/article/functional-desgin-ppp/clojure/18-concurrency-system.md +475 -0
- package/lib/assets/docs/article/functional-desgin-ppp/clojure/19-wator-simulation.md +739 -0
- package/lib/assets/docs/article/functional-desgin-ppp/clojure/20-pattern-interactions.md +562 -0
- package/lib/assets/docs/article/functional-desgin-ppp/clojure/21-best-practices.md +506 -0
- package/lib/assets/docs/article/functional-desgin-ppp/clojure/22-oo-to-fp-migration.md +526 -0
- package/lib/assets/docs/article/functional-desgin-ppp/clojure/index.md +197 -0
- package/lib/assets/docs/article/functional-desgin-ppp/elixir/01-immutability-and-data-transformation.md +381 -0
- package/lib/assets/docs/article/functional-desgin-ppp/elixir/02-function-composition.md +374 -0
- package/lib/assets/docs/article/functional-desgin-ppp/elixir/03-polymorphism.md +375 -0
- package/lib/assets/docs/article/functional-desgin-ppp/elixir/04-data-validation.md +195 -0
- package/lib/assets/docs/article/functional-desgin-ppp/elixir/05-property-based-testing.md +268 -0
- package/lib/assets/docs/article/functional-desgin-ppp/elixir/06-tdd-and-fp.md +294 -0
- package/lib/assets/docs/article/functional-desgin-ppp/elixir/07-effects-and-pure-functions.md +164 -0
- package/lib/assets/docs/article/functional-desgin-ppp/elixir/08-error-handling-strategies.md +168 -0
- package/lib/assets/docs/article/functional-desgin-ppp/elixir/09-io-and-external-systems.md +254 -0
- package/lib/assets/docs/article/functional-desgin-ppp/elixir/10-concurrency-patterns.md +269 -0
- package/lib/assets/docs/article/functional-desgin-ppp/elixir/11-command-pattern.md +148 -0
- package/lib/assets/docs/article/functional-desgin-ppp/elixir/12-visitor-pattern.md +176 -0
- package/lib/assets/docs/article/functional-desgin-ppp/elixir/13-abstract-factory-pattern.md +604 -0
- package/lib/assets/docs/article/functional-desgin-ppp/elixir/14-abstract-server-pattern.md +729 -0
- package/lib/assets/docs/article/functional-desgin-ppp/elixir/15-gossiping-bus-drivers.md +291 -0
- package/lib/assets/docs/article/functional-desgin-ppp/elixir/16-payroll-system.md +420 -0
- package/lib/assets/docs/article/functional-desgin-ppp/elixir/17-video-rental-system.md +319 -0
- package/lib/assets/docs/article/functional-desgin-ppp/elixir/18-concurrency-system.md +466 -0
- package/lib/assets/docs/article/functional-desgin-ppp/elixir/19-wator-simulation.md +523 -0
- package/lib/assets/docs/article/functional-desgin-ppp/elixir/20-pattern-interactions.md +287 -0
- package/lib/assets/docs/article/functional-desgin-ppp/elixir/21-best-practices.md +340 -0
- package/lib/assets/docs/article/functional-desgin-ppp/elixir/22-oo-to-fp-migration.md +395 -0
- package/lib/assets/docs/article/functional-desgin-ppp/elixir/index.md +204 -0
- package/lib/assets/docs/article/functional-desgin-ppp/fsharp/01-immutability-and-data-transformation.md +382 -0
- package/lib/assets/docs/article/functional-desgin-ppp/fsharp/02-function-composition.md +452 -0
- package/lib/assets/docs/article/functional-desgin-ppp/fsharp/03-polymorphism.md +495 -0
- package/lib/assets/docs/article/functional-desgin-ppp/fsharp/04-data-validation.md +416 -0
- package/lib/assets/docs/article/functional-desgin-ppp/fsharp/05-property-based-testing.md +382 -0
- package/lib/assets/docs/article/functional-desgin-ppp/fsharp/06-tdd-functional.md +687 -0
- package/lib/assets/docs/article/functional-desgin-ppp/fsharp/07-composite-pattern.md +442 -0
- package/lib/assets/docs/article/functional-desgin-ppp/fsharp/08-decorator-pattern.md +479 -0
- package/lib/assets/docs/article/functional-desgin-ppp/fsharp/09-adapter-pattern.md +479 -0
- package/lib/assets/docs/article/functional-desgin-ppp/fsharp/10-strategy-pattern.md +427 -0
- package/lib/assets/docs/article/functional-desgin-ppp/fsharp/11-command-pattern.md +428 -0
- package/lib/assets/docs/article/functional-desgin-ppp/fsharp/12-visitor-pattern.md +339 -0
- package/lib/assets/docs/article/functional-desgin-ppp/fsharp/13-abstract-factory-pattern.md +309 -0
- package/lib/assets/docs/article/functional-desgin-ppp/fsharp/14-abstract-server-pattern.md +596 -0
- package/lib/assets/docs/article/functional-desgin-ppp/fsharp/15-gossiping-bus-drivers.md +353 -0
- package/lib/assets/docs/article/functional-desgin-ppp/fsharp/16-payroll-system.md +350 -0
- package/lib/assets/docs/article/functional-desgin-ppp/fsharp/17-video-rental-system.md +412 -0
- package/lib/assets/docs/article/functional-desgin-ppp/fsharp/18-concurrency-system.md +367 -0
- package/lib/assets/docs/article/functional-desgin-ppp/fsharp/19-wator-simulation.md +401 -0
- package/lib/assets/docs/article/functional-desgin-ppp/fsharp/20-pattern-interactions.md +291 -0
- package/lib/assets/docs/article/functional-desgin-ppp/fsharp/21-best-practices.md +320 -0
- package/lib/assets/docs/article/functional-desgin-ppp/fsharp/22-oo-to-fp-migration.md +322 -0
- package/lib/assets/docs/article/functional-desgin-ppp/fsharp/index.md +230 -0
- package/lib/assets/docs/article/functional-desgin-ppp/haskell/01-immutability-and-data-transformation.md +298 -0
- package/lib/assets/docs/article/functional-desgin-ppp/haskell/02-function-composition.md +304 -0
- package/lib/assets/docs/article/functional-desgin-ppp/haskell/03-polymorphism.md +362 -0
- package/lib/assets/docs/article/functional-desgin-ppp/haskell/04-data-validation.md +257 -0
- package/lib/assets/docs/article/functional-desgin-ppp/haskell/05-property-based-testing.md +254 -0
- package/lib/assets/docs/article/functional-desgin-ppp/haskell/06-tdd-functional.md +283 -0
- package/lib/assets/docs/article/functional-desgin-ppp/haskell/07-composite-pattern.md +395 -0
- package/lib/assets/docs/article/functional-desgin-ppp/haskell/08-decorator-pattern.md +319 -0
- package/lib/assets/docs/article/functional-desgin-ppp/haskell/09-adapter-pattern.md +382 -0
- package/lib/assets/docs/article/functional-desgin-ppp/haskell/10-strategy-pattern.md +287 -0
- package/lib/assets/docs/article/functional-desgin-ppp/haskell/11-command-pattern.md +303 -0
- package/lib/assets/docs/article/functional-desgin-ppp/haskell/12-visitor-pattern.md +326 -0
- package/lib/assets/docs/article/functional-desgin-ppp/haskell/13-abstract-factory-pattern.md +332 -0
- package/lib/assets/docs/article/functional-desgin-ppp/haskell/14-abstract-server-pattern.md +379 -0
- package/lib/assets/docs/article/functional-desgin-ppp/haskell/15-gossiping-bus-drivers.md +175 -0
- package/lib/assets/docs/article/functional-desgin-ppp/haskell/16-payroll-system.md +219 -0
- package/lib/assets/docs/article/functional-desgin-ppp/haskell/17-video-rental-system.md +244 -0
- package/lib/assets/docs/article/functional-desgin-ppp/haskell/18-concurrency-system.md +363 -0
- package/lib/assets/docs/article/functional-desgin-ppp/haskell/19-wator-simulation.md +438 -0
- package/lib/assets/docs/article/functional-desgin-ppp/haskell/20-pattern-interactions.md +323 -0
- package/lib/assets/docs/article/functional-desgin-ppp/haskell/21-best-practices.md +403 -0
- package/lib/assets/docs/article/functional-desgin-ppp/haskell/22-oo-to-fp-migration.md +469 -0
- package/lib/assets/docs/article/functional-desgin-ppp/haskell/index.md +174 -0
- package/lib/assets/docs/article/functional-desgin-ppp/index.md +90 -0
- package/lib/assets/docs/article/functional-desgin-ppp/rust/01-immutability-and-data-transformation.md +448 -0
- package/lib/assets/docs/article/functional-desgin-ppp/rust/02-function-composition.md +463 -0
- package/lib/assets/docs/article/functional-desgin-ppp/rust/03-polymorphism.md +425 -0
- package/lib/assets/docs/article/functional-desgin-ppp/rust/04-data-validation.md +273 -0
- package/lib/assets/docs/article/functional-desgin-ppp/rust/05-property-based-testing.md +247 -0
- package/lib/assets/docs/article/functional-desgin-ppp/rust/06-tdd-and-functional.md +841 -0
- package/lib/assets/docs/article/functional-desgin-ppp/rust/07-composite-pattern.md +384 -0
- package/lib/assets/docs/article/functional-desgin-ppp/rust/08-decorator-pattern.md +383 -0
- package/lib/assets/docs/article/functional-desgin-ppp/rust/09-adapter-pattern.md +339 -0
- package/lib/assets/docs/article/functional-desgin-ppp/rust/10-strategy-pattern.md +331 -0
- package/lib/assets/docs/article/functional-desgin-ppp/rust/11-command-pattern.md +356 -0
- package/lib/assets/docs/article/functional-desgin-ppp/rust/12-visitor-pattern.md +379 -0
- package/lib/assets/docs/article/functional-desgin-ppp/rust/13-abstract-factory-pattern.md +361 -0
- package/lib/assets/docs/article/functional-desgin-ppp/rust/14-abstract-server-pattern.md +392 -0
- package/lib/assets/docs/article/functional-desgin-ppp/rust/15-gossiping-bus-drivers.md +300 -0
- package/lib/assets/docs/article/functional-desgin-ppp/rust/16-payroll-system.md +297 -0
- package/lib/assets/docs/article/functional-desgin-ppp/rust/17-video-rental-system.md +304 -0
- package/lib/assets/docs/article/functional-desgin-ppp/rust/18-concurrency-system.md +315 -0
- package/lib/assets/docs/article/functional-desgin-ppp/rust/19-wator-simulation.md +311 -0
- package/lib/assets/docs/article/functional-desgin-ppp/rust/20-pattern-interactions.md +304 -0
- package/lib/assets/docs/article/functional-desgin-ppp/rust/21-best-practices.md +336 -0
- package/lib/assets/docs/article/functional-desgin-ppp/rust/22-oo-to-fp-migration.md +349 -0
- package/lib/assets/docs/article/functional-desgin-ppp/rust/index.md +199 -0
- package/lib/assets/docs/article/functional-desgin-ppp/scala/01-immutability-and-data-transformation.md +326 -0
- package/lib/assets/docs/article/functional-desgin-ppp/scala/02-function-composition.md +348 -0
- package/lib/assets/docs/article/functional-desgin-ppp/scala/03-polymorphism.md +357 -0
- package/lib/assets/docs/article/functional-desgin-ppp/scala/04-data-validation.md +364 -0
- package/lib/assets/docs/article/functional-desgin-ppp/scala/05-property-based-testing.md +515 -0
- package/lib/assets/docs/article/functional-desgin-ppp/scala/06-tdd-functional.md +557 -0
- package/lib/assets/docs/article/functional-desgin-ppp/scala/07-composite-pattern.md +363 -0
- package/lib/assets/docs/article/functional-desgin-ppp/scala/08-decorator-pattern.md +327 -0
- package/lib/assets/docs/article/functional-desgin-ppp/scala/09-adapter-pattern.md +517 -0
- package/lib/assets/docs/article/functional-desgin-ppp/scala/10-strategy-pattern.md +441 -0
- package/lib/assets/docs/article/functional-desgin-ppp/scala/11-command-pattern.md +407 -0
- package/lib/assets/docs/article/functional-desgin-ppp/scala/12-visitor-pattern.md +379 -0
- package/lib/assets/docs/article/functional-desgin-ppp/scala/13-abstract-factory-pattern.md +398 -0
- package/lib/assets/docs/article/functional-desgin-ppp/scala/14-abstract-server-pattern.md +476 -0
- package/lib/assets/docs/article/functional-desgin-ppp/scala/15-gossiping-bus-drivers.md +389 -0
- package/lib/assets/docs/article/functional-desgin-ppp/scala/16-payroll-system.md +342 -0
- package/lib/assets/docs/article/functional-desgin-ppp/scala/17-video-rental-system.md +324 -0
- package/lib/assets/docs/article/functional-desgin-ppp/scala/18-concurrency-system.md +730 -0
- package/lib/assets/docs/article/functional-desgin-ppp/scala/19-wator-simulation.md +624 -0
- package/lib/assets/docs/article/functional-desgin-ppp/scala/20-pattern-interactions.md +512 -0
- package/lib/assets/docs/article/functional-desgin-ppp/scala/21-best-practices.md +427 -0
- package/lib/assets/docs/article/functional-desgin-ppp/scala/22-oo-to-fp-migration.md +682 -0
- package/lib/assets/docs/article/functional-desgin-ppp/scala/index.md +199 -0
- package/lib/assets/docs/article/getting-start-tdd/clojure/01-todo-list-and-first-test.md +166 -0
- package/lib/assets/docs/article/getting-start-tdd/clojure/02-fake-it-and-triangulation.md +162 -0
- package/lib/assets/docs/article/getting-start-tdd/clojure/03-obvious-implementation-and-refactoring.md +135 -0
- package/lib/assets/docs/article/getting-start-tdd/clojure/04-version-control-and-conventional-commits.md +88 -0
- package/lib/assets/docs/article/getting-start-tdd/clojure/05-package-management-and-static-analysis.md +299 -0
- package/lib/assets/docs/article/getting-start-tdd/clojure/06-task-runner-and-ci-cd.md +241 -0
- package/lib/assets/docs/article/getting-start-tdd/clojure/07-protocols-and-records.md +131 -0
- package/lib/assets/docs/article/getting-start-tdd/clojure/08-multimethods-and-design-patterns.md +130 -0
- package/lib/assets/docs/article/getting-start-tdd/clojure/09-namespaces-and-module-design.md +127 -0
- package/lib/assets/docs/article/getting-start-tdd/clojure/10-higher-order-functions-and-composition.md +114 -0
- package/lib/assets/docs/article/getting-start-tdd/clojure/11-persistent-data-and-pipeline.md +138 -0
- package/lib/assets/docs/article/getting-start-tdd/clojure/12-error-handling-and-spec.md +161 -0
- package/lib/assets/docs/article/getting-start-tdd/clojure/index.md +65 -0
- package/lib/assets/docs/article/getting-start-tdd/csharp/chapter01.md +232 -0
- package/lib/assets/docs/article/getting-start-tdd/csharp/chapter02.md +244 -0
- package/lib/assets/docs/article/getting-start-tdd/csharp/chapter03.md +202 -0
- package/lib/assets/docs/article/getting-start-tdd/csharp/chapter04.md +92 -0
- package/lib/assets/docs/article/getting-start-tdd/csharp/chapter05.md +256 -0
- package/lib/assets/docs/article/getting-start-tdd/csharp/chapter06.md +195 -0
- package/lib/assets/docs/article/getting-start-tdd/csharp/chapter07.md +214 -0
- package/lib/assets/docs/article/getting-start-tdd/csharp/chapter08.md +249 -0
- package/lib/assets/docs/article/getting-start-tdd/csharp/chapter09.md +174 -0
- package/lib/assets/docs/article/getting-start-tdd/csharp/chapter10.md +166 -0
- package/lib/assets/docs/article/getting-start-tdd/csharp/chapter11.md +192 -0
- package/lib/assets/docs/article/getting-start-tdd/csharp/chapter12.md +211 -0
- package/lib/assets/docs/article/getting-start-tdd/csharp/index.md +83 -0
- package/lib/assets/docs/article/getting-start-tdd/elixir/01-todo-list-and-first-test.md +87 -0
- package/lib/assets/docs/article/getting-start-tdd/elixir/02-fake-it-and-triangulation.md +95 -0
- package/lib/assets/docs/article/getting-start-tdd/elixir/03-obvious-implementation-and-refactoring.md +109 -0
- package/lib/assets/docs/article/getting-start-tdd/elixir/04-version-control-and-conventional-commits.md +96 -0
- package/lib/assets/docs/article/getting-start-tdd/elixir/05-package-management-and-static-analysis.md +88 -0
- package/lib/assets/docs/article/getting-start-tdd/elixir/06-task-runner-and-ci-cd.md +71 -0
- package/lib/assets/docs/article/getting-start-tdd/elixir/07-structs-and-protocols.md +110 -0
- package/lib/assets/docs/article/getting-start-tdd/elixir/08-pattern-matching-and-guards.md +108 -0
- package/lib/assets/docs/article/getting-start-tdd/elixir/09-module-design-and-behaviours.md +104 -0
- package/lib/assets/docs/article/getting-start-tdd/elixir/10-higher-order-functions-and-pipeline.md +178 -0
- package/lib/assets/docs/article/getting-start-tdd/elixir/11-stream-and-lazy-evaluation.md +142 -0
- package/lib/assets/docs/article/getting-start-tdd/elixir/12-error-handling-and-with.md +145 -0
- package/lib/assets/docs/article/getting-start-tdd/elixir/index.md +35 -0
- package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter01.md +202 -0
- package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter02.md +246 -0
- package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter03.md +218 -0
- package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter04.md +179 -0
- package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter05.md +267 -0
- package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter06.md +190 -0
- package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter07.md +161 -0
- package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter08.md +175 -0
- package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter09.md +222 -0
- package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter10.md +189 -0
- package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter11.md +212 -0
- package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter12.md +215 -0
- package/lib/assets/docs/article/getting-start-tdd/fsharp/index.md +71 -0
- package/lib/assets/docs/article/getting-start-tdd/go/01-todo-list-and-first-test.md +213 -0
- package/lib/assets/docs/article/getting-start-tdd/go/02-fake-it-and-triangulation.md +302 -0
- package/lib/assets/docs/article/getting-start-tdd/go/03-obvious-implementation-and-refactoring.md +339 -0
- package/lib/assets/docs/article/getting-start-tdd/go/04-version-control-and-conventional-commits.md +112 -0
- package/lib/assets/docs/article/getting-start-tdd/go/05-package-management-and-static-analysis.md +272 -0
- package/lib/assets/docs/article/getting-start-tdd/go/06-task-runner-and-ci-cd.md +233 -0
- package/lib/assets/docs/article/getting-start-tdd/go/07-encapsulation-and-polymorphism.md +394 -0
- package/lib/assets/docs/article/getting-start-tdd/go/08-design-patterns.md +422 -0
- package/lib/assets/docs/article/getting-start-tdd/go/09-solid-principles-and-module-design.md +400 -0
- package/lib/assets/docs/article/getting-start-tdd/go/10-higher-order-functions-and-composition.md +226 -0
- package/lib/assets/docs/article/getting-start-tdd/go/11-immutable-data-and-pipeline.md +296 -0
- package/lib/assets/docs/article/getting-start-tdd/go/12-error-handling-and-type-safety.md +411 -0
- package/lib/assets/docs/article/getting-start-tdd/go/index.md +83 -0
- package/lib/assets/docs/article/getting-start-tdd/haskell/01-todo-list-and-first-test.md +279 -0
- package/lib/assets/docs/article/getting-start-tdd/haskell/02-fake-it-and-triangulation.md +337 -0
- package/lib/assets/docs/article/getting-start-tdd/haskell/03-obvious-implementation-and-refactoring.md +257 -0
- package/lib/assets/docs/article/getting-start-tdd/haskell/04-version-control-and-conventional-commits.md +182 -0
- package/lib/assets/docs/article/getting-start-tdd/haskell/05-package-management-and-static-analysis.md +313 -0
- package/lib/assets/docs/article/getting-start-tdd/haskell/06-task-runner-and-ci-cd.md +309 -0
- package/lib/assets/docs/article/getting-start-tdd/haskell/07-algebraic-data-types-and-type-classes.md +412 -0
- package/lib/assets/docs/article/getting-start-tdd/haskell/08-pattern-matching-and-guards.md +390 -0
- package/lib/assets/docs/article/getting-start-tdd/haskell/09-module-design-and-smart-constructors.md +461 -0
- package/lib/assets/docs/article/getting-start-tdd/haskell/10-higher-order-functions-and-currying.md +434 -0
- package/lib/assets/docs/article/getting-start-tdd/haskell/11-function-composition-and-point-free.md +392 -0
- package/lib/assets/docs/article/getting-start-tdd/haskell/12-monad-and-error-handling.md +631 -0
- package/lib/assets/docs/article/getting-start-tdd/haskell/index.md +49 -0
- package/lib/assets/docs/article/getting-start-tdd/index.md +93 -0
- package/lib/assets/docs/article/getting-start-tdd/integration/01-language-overview.md +375 -0
- package/lib/assets/docs/article/getting-start-tdd/integration/02-test-framework-comparison.md +349 -0
- package/lib/assets/docs/article/getting-start-tdd/integration/03-tdd-pattern-comparison.md +445 -0
- package/lib/assets/docs/article/getting-start-tdd/integration/04-type-system-comparison.md +405 -0
- package/lib/assets/docs/article/getting-start-tdd/integration/05-dev-environment-comparison.md +330 -0
- package/lib/assets/docs/article/getting-start-tdd/integration/06-learning-roadmap.md +274 -0
- package/lib/assets/docs/article/getting-start-tdd/integration/index.md +69 -0
- package/lib/assets/docs/article/getting-start-tdd/java/01-todo-list-and-first-test.md +234 -0
- package/lib/assets/docs/article/getting-start-tdd/java/02-fake-it-and-triangulation.md +261 -0
- package/lib/assets/docs/article/getting-start-tdd/java/03-obvious-implementation-and-refactoring.md +185 -0
- package/lib/assets/docs/article/getting-start-tdd/java/04-version-control-and-conventional-commits.md +115 -0
- package/lib/assets/docs/article/getting-start-tdd/java/05-package-management-and-static-analysis.md +382 -0
- package/lib/assets/docs/article/getting-start-tdd/java/06-task-runner-and-ci-cd.md +272 -0
- package/lib/assets/docs/article/getting-start-tdd/java/07-encapsulation-and-polymorphism.md +626 -0
- package/lib/assets/docs/article/getting-start-tdd/java/08-design-patterns.md +393 -0
- package/lib/assets/docs/article/getting-start-tdd/java/09-solid-principles-and-module-design.md +310 -0
- package/lib/assets/docs/article/getting-start-tdd/java/10-higher-order-functions-and-composition.md +188 -0
- package/lib/assets/docs/article/getting-start-tdd/java/11-immutable-data-and-pipeline.md +167 -0
- package/lib/assets/docs/article/getting-start-tdd/java/12-error-handling-and-type-safety.md +205 -0
- package/lib/assets/docs/article/getting-start-tdd/java/index.md +61 -0
- package/lib/assets/docs/article/getting-start-tdd/node/01-todo-list-and-first-test.md +244 -0
- package/lib/assets/docs/article/getting-start-tdd/node/02-fake-it-and-triangulation.md +262 -0
- package/lib/assets/docs/article/getting-start-tdd/node/03-obvious-implementation-and-refactoring.md +169 -0
- package/lib/assets/docs/article/getting-start-tdd/node/04-version-control-and-conventional-commits.md +112 -0
- package/lib/assets/docs/article/getting-start-tdd/node/05-package-management-and-static-analysis.md +314 -0
- package/lib/assets/docs/article/getting-start-tdd/node/06-task-runner-and-ci-cd.md +235 -0
- package/lib/assets/docs/article/getting-start-tdd/node/07-encapsulation-and-polymorphism.md +327 -0
- package/lib/assets/docs/article/getting-start-tdd/node/08-design-patterns.md +322 -0
- package/lib/assets/docs/article/getting-start-tdd/node/09-solid-principles-and-module-design.md +285 -0
- package/lib/assets/docs/article/getting-start-tdd/node/10-higher-order-functions-and-composition.md +199 -0
- package/lib/assets/docs/article/getting-start-tdd/node/11-immutable-data-and-pipeline.md +207 -0
- package/lib/assets/docs/article/getting-start-tdd/node/12-error-handling-and-type-safety.md +295 -0
- package/lib/assets/docs/article/getting-start-tdd/node/index.md +56 -0
- package/lib/assets/docs/article/getting-start-tdd/php/01-todo-list-and-first-test.md +259 -0
- package/lib/assets/docs/article/getting-start-tdd/php/02-fake-it-and-triangulation.md +200 -0
- package/lib/assets/docs/article/getting-start-tdd/php/03-obvious-implementation-and-refactoring.md +248 -0
- package/lib/assets/docs/article/getting-start-tdd/php/04-version-control-and-conventional-commits.md +141 -0
- package/lib/assets/docs/article/getting-start-tdd/php/05-package-management-and-static-analysis.md +410 -0
- package/lib/assets/docs/article/getting-start-tdd/php/06-task-runner-and-ci-cd.md +321 -0
- package/lib/assets/docs/article/getting-start-tdd/php/07-encapsulation-and-polymorphism.md +372 -0
- package/lib/assets/docs/article/getting-start-tdd/php/08-design-patterns.md +453 -0
- package/lib/assets/docs/article/getting-start-tdd/php/09-solid-principles-and-module-design.md +460 -0
- package/lib/assets/docs/article/getting-start-tdd/php/10-higher-order-functions-and-composition.md +182 -0
- package/lib/assets/docs/article/getting-start-tdd/php/11-immutable-data-and-pipeline.md +266 -0
- package/lib/assets/docs/article/getting-start-tdd/php/12-error-handling-and-type-safety.md +308 -0
- package/lib/assets/docs/article/getting-start-tdd/php/index.md +84 -0
- package/lib/assets/docs/article/getting-start-tdd/python/01-todo-list-and-first-test.md +201 -0
- package/lib/assets/docs/article/getting-start-tdd/python/02-fake-it-and-triangulation.md +247 -0
- package/lib/assets/docs/article/getting-start-tdd/python/03-obvious-implementation-and-refactoring.md +199 -0
- package/lib/assets/docs/article/getting-start-tdd/python/04-version-control-and-conventional-commits.md +87 -0
- package/lib/assets/docs/article/getting-start-tdd/python/05-package-management-and-static-analysis.md +274 -0
- package/lib/assets/docs/article/getting-start-tdd/python/06-task-runner-and-ci-cd.md +190 -0
- package/lib/assets/docs/article/getting-start-tdd/python/07-encapsulation-and-polymorphism.md +208 -0
- package/lib/assets/docs/article/getting-start-tdd/python/08-design-patterns.md +172 -0
- package/lib/assets/docs/article/getting-start-tdd/python/09-solid-principles-and-module-design.md +130 -0
- package/lib/assets/docs/article/getting-start-tdd/python/10-higher-order-functions-and-composition.md +122 -0
- package/lib/assets/docs/article/getting-start-tdd/python/11-immutable-data-and-pipeline.md +116 -0
- package/lib/assets/docs/article/getting-start-tdd/python/12-error-handling-and-type-safety.md +126 -0
- package/lib/assets/docs/article/getting-start-tdd/python/index.md +55 -0
- package/lib/assets/docs/article/getting-start-tdd/ruby/01-todo-list-and-first-test.md +231 -0
- package/lib/assets/docs/article/getting-start-tdd/ruby/02-fake-it-and-triangulation.md +238 -0
- package/lib/assets/docs/article/getting-start-tdd/ruby/03-obvious-implementation-and-refactoring.md +228 -0
- package/lib/assets/docs/article/getting-start-tdd/ruby/04-version-control-and-conventional-commits.md +112 -0
- package/lib/assets/docs/article/getting-start-tdd/ruby/05-package-management-and-static-analysis.md +287 -0
- package/lib/assets/docs/article/getting-start-tdd/ruby/06-task-runner-and-ci-cd.md +248 -0
- package/lib/assets/docs/article/getting-start-tdd/ruby/07-encapsulation-and-polymorphism.md +279 -0
- package/lib/assets/docs/article/getting-start-tdd/ruby/08-design-patterns.md +329 -0
- package/lib/assets/docs/article/getting-start-tdd/ruby/09-solid-principles-and-module-design.md +196 -0
- package/lib/assets/docs/article/getting-start-tdd/ruby/10-higher-order-functions-and-composition.md +175 -0
- package/lib/assets/docs/article/getting-start-tdd/ruby/11-immutable-data-and-pipeline.md +233 -0
- package/lib/assets/docs/article/getting-start-tdd/ruby/12-error-handling-and-type-safety.md +398 -0
- package/lib/assets/docs/article/getting-start-tdd/ruby/index.md +83 -0
- package/lib/assets/docs/article/getting-start-tdd/rust/01-todo-list-and-first-test.md +211 -0
- package/lib/assets/docs/article/getting-start-tdd/rust/02-fake-it-and-triangulation.md +264 -0
- package/lib/assets/docs/article/getting-start-tdd/rust/03-obvious-implementation-and-refactoring.md +233 -0
- package/lib/assets/docs/article/getting-start-tdd/rust/04-version-control-and-conventional-commits.md +92 -0
- package/lib/assets/docs/article/getting-start-tdd/rust/05-package-management-and-static-analysis.md +212 -0
- package/lib/assets/docs/article/getting-start-tdd/rust/06-task-runner-and-ci-cd.md +164 -0
- package/lib/assets/docs/article/getting-start-tdd/rust/07-encapsulation-and-polymorphism.md +142 -0
- package/lib/assets/docs/article/getting-start-tdd/rust/08-design-patterns.md +145 -0
- package/lib/assets/docs/article/getting-start-tdd/rust/09-solid-principles-and-module-design.md +110 -0
- package/lib/assets/docs/article/getting-start-tdd/rust/10-higher-order-functions-and-composition.md +94 -0
- package/lib/assets/docs/article/getting-start-tdd/rust/11-immutable-data-and-pipeline.md +105 -0
- package/lib/assets/docs/article/getting-start-tdd/rust/12-error-handling-and-type-safety.md +112 -0
- package/lib/assets/docs/article/getting-start-tdd/rust/index.md +83 -0
- package/lib/assets/docs/article/getting-start-tdd/scala/01-todo-list-and-first-test.md +111 -0
- package/lib/assets/docs/article/getting-start-tdd/scala/02-fake-it-and-triangulation.md +107 -0
- package/lib/assets/docs/article/getting-start-tdd/scala/03-obvious-implementation-and-refactoring.md +99 -0
- package/lib/assets/docs/article/getting-start-tdd/scala/04-version-control-and-conventional-commits.md +123 -0
- package/lib/assets/docs/article/getting-start-tdd/scala/05-package-management-and-static-analysis.md +196 -0
- package/lib/assets/docs/article/getting-start-tdd/scala/06-task-runner-and-ci-cd.md +186 -0
- package/lib/assets/docs/article/getting-start-tdd/scala/07-case-classes-and-traits.md +139 -0
- package/lib/assets/docs/article/getting-start-tdd/scala/08-pattern-matching-and-sealed-traits.md +106 -0
- package/lib/assets/docs/article/getting-start-tdd/scala/09-packages-and-module-design.md +75 -0
- package/lib/assets/docs/article/getting-start-tdd/scala/10-higher-order-functions-and-composition.md +104 -0
- package/lib/assets/docs/article/getting-start-tdd/scala/11-collections-and-lazy-evaluation.md +94 -0
- package/lib/assets/docs/article/getting-start-tdd/scala/12-error-handling-and-type-safety.md +92 -0
- package/lib/assets/docs/article/getting-start-tdd/scala/index.md +65 -0
- package/lib/assets/docs/article/grokking-concurrency/all/index.md +404 -0
- package/lib/assets/docs/article/grokking-concurrency/all/part-1-ch02-sequential.md +554 -0
- package/lib/assets/docs/article/grokking-concurrency/all/part-2-ch04-05-threads.md +469 -0
- package/lib/assets/docs/article/grokking-concurrency/all/part-3-ch06-multitasking.md +520 -0
- package/lib/assets/docs/article/grokking-concurrency/all/part-4-ch07-parallel-patterns.md +420 -0
- package/lib/assets/docs/article/grokking-concurrency/all/part-5-ch08-09-synchronization.md +510 -0
- package/lib/assets/docs/article/grokking-concurrency/all/part-6-ch10-11-nonblocking-io.md +435 -0
- package/lib/assets/docs/article/grokking-concurrency/all/part-7-ch12-async.md +465 -0
- package/lib/assets/docs/article/grokking-concurrency/all/part-8-ch13-mapreduce.md +377 -0
- package/lib/assets/docs/article/grokking-concurrency/clojure/index.md +116 -0
- package/lib/assets/docs/article/grokking-concurrency/clojure/part-1.md +108 -0
- package/lib/assets/docs/article/grokking-concurrency/clojure/part-2.md +101 -0
- package/lib/assets/docs/article/grokking-concurrency/clojure/part-3.md +122 -0
- package/lib/assets/docs/article/grokking-concurrency/clojure/part-4.md +123 -0
- package/lib/assets/docs/article/grokking-concurrency/clojure/part-5.md +118 -0
- package/lib/assets/docs/article/grokking-concurrency/clojure/part-6.md +89 -0
- package/lib/assets/docs/article/grokking-concurrency/clojure/part-7.md +100 -0
- package/lib/assets/docs/article/grokking-concurrency/clojure/part-8.md +120 -0
- package/lib/assets/docs/article/grokking-concurrency/csharp/index.md +101 -0
- package/lib/assets/docs/article/grokking-concurrency/csharp/part-1.md +97 -0
- package/lib/assets/docs/article/grokking-concurrency/csharp/part-2.md +123 -0
- package/lib/assets/docs/article/grokking-concurrency/csharp/part-3.md +101 -0
- package/lib/assets/docs/article/grokking-concurrency/csharp/part-4.md +112 -0
- package/lib/assets/docs/article/grokking-concurrency/csharp/part-5.md +99 -0
- package/lib/assets/docs/article/grokking-concurrency/csharp/part-6.md +61 -0
- package/lib/assets/docs/article/grokking-concurrency/csharp/part-7.md +84 -0
- package/lib/assets/docs/article/grokking-concurrency/csharp/part-8.md +92 -0
- package/lib/assets/docs/article/grokking-concurrency/fsharp/index.md +65 -0
- package/lib/assets/docs/article/grokking-concurrency/fsharp/part-1.md +80 -0
- package/lib/assets/docs/article/grokking-concurrency/fsharp/part-2.md +103 -0
- package/lib/assets/docs/article/grokking-concurrency/fsharp/part-3.md +94 -0
- package/lib/assets/docs/article/grokking-concurrency/fsharp/part-4.md +110 -0
- package/lib/assets/docs/article/grokking-concurrency/fsharp/part-5.md +104 -0
- package/lib/assets/docs/article/grokking-concurrency/fsharp/part-6.md +93 -0
- package/lib/assets/docs/article/grokking-concurrency/fsharp/part-7.md +121 -0
- package/lib/assets/docs/article/grokking-concurrency/fsharp/part-8.md +107 -0
- package/lib/assets/docs/article/grokking-concurrency/haskell/index.md +248 -0
- package/lib/assets/docs/article/grokking-concurrency/haskell/part-1.md +96 -0
- package/lib/assets/docs/article/grokking-concurrency/haskell/part-2.md +96 -0
- package/lib/assets/docs/article/grokking-concurrency/haskell/part-3.md +91 -0
- package/lib/assets/docs/article/grokking-concurrency/haskell/part-4.md +106 -0
- package/lib/assets/docs/article/grokking-concurrency/haskell/part-5.md +99 -0
- package/lib/assets/docs/article/grokking-concurrency/haskell/part-6.md +95 -0
- package/lib/assets/docs/article/grokking-concurrency/haskell/part-7.md +111 -0
- package/lib/assets/docs/article/grokking-concurrency/haskell/part-8.md +118 -0
- package/lib/assets/docs/article/grokking-concurrency/index.md +66 -0
- package/lib/assets/docs/article/grokking-concurrency/java/index.md +102 -0
- package/lib/assets/docs/article/grokking-concurrency/java/part-1.md +308 -0
- package/lib/assets/docs/article/grokking-concurrency/java/part-2.md +334 -0
- package/lib/assets/docs/article/grokking-concurrency/java/part-3.md +221 -0
- package/lib/assets/docs/article/grokking-concurrency/java/part-4.md +213 -0
- package/lib/assets/docs/article/grokking-concurrency/java/part-5.md +112 -0
- package/lib/assets/docs/article/grokking-concurrency/java/part-6.md +69 -0
- package/lib/assets/docs/article/grokking-concurrency/java/part-7.md +101 -0
- package/lib/assets/docs/article/grokking-concurrency/java/part-8.md +101 -0
- package/lib/assets/docs/article/grokking-concurrency/python/index.md +313 -0
- package/lib/assets/docs/article/grokking-concurrency/python/part-1.md +239 -0
- package/lib/assets/docs/article/grokking-concurrency/python/part-2.md +418 -0
- package/lib/assets/docs/article/grokking-concurrency/python/part-3.md +227 -0
- package/lib/assets/docs/article/grokking-concurrency/python/part-4.md +299 -0
- package/lib/assets/docs/article/grokking-concurrency/python/part-5.md +315 -0
- package/lib/assets/docs/article/grokking-concurrency/python/part-6.md +297 -0
- package/lib/assets/docs/article/grokking-concurrency/python/part-7.md +314 -0
- package/lib/assets/docs/article/grokking-concurrency/python/part-8.md +360 -0
- package/lib/assets/docs/article/grokking-concurrency/rust/index.md +270 -0
- package/lib/assets/docs/article/grokking-concurrency/rust/part-1.md +108 -0
- package/lib/assets/docs/article/grokking-concurrency/rust/part-2.md +120 -0
- package/lib/assets/docs/article/grokking-concurrency/rust/part-3.md +126 -0
- package/lib/assets/docs/article/grokking-concurrency/rust/part-4.md +175 -0
- package/lib/assets/docs/article/grokking-concurrency/rust/part-5.md +158 -0
- package/lib/assets/docs/article/grokking-concurrency/rust/part-6.md +94 -0
- package/lib/assets/docs/article/grokking-concurrency/rust/part-7.md +133 -0
- package/lib/assets/docs/article/grokking-concurrency/rust/part-8.md +155 -0
- package/lib/assets/docs/article/grokking-concurrency/scala/index.md +69 -0
- package/lib/assets/docs/article/grokking-concurrency/scala/part-1.md +78 -0
- package/lib/assets/docs/article/grokking-concurrency/scala/part-2.md +112 -0
- package/lib/assets/docs/article/grokking-concurrency/scala/part-3.md +93 -0
- package/lib/assets/docs/article/grokking-concurrency/scala/part-4.md +110 -0
- package/lib/assets/docs/article/grokking-concurrency/scala/part-5.md +119 -0
- package/lib/assets/docs/article/grokking-concurrency/scala/part-6.md +83 -0
- package/lib/assets/docs/article/grokking-concurrency/scala/part-7.md +131 -0
- package/lib/assets/docs/article/grokking-concurrency/scala/part-8.md +129 -0
- package/lib/assets/docs/article/grokkingfp/all/index.md +368 -0
- package/lib/assets/docs/article/grokkingfp/all/part-1-ch01-fp-introduction.md +530 -0
- package/lib/assets/docs/article/grokkingfp/all/part-1-ch02-pure-functions.md +923 -0
- package/lib/assets/docs/article/grokkingfp/all/part-2-ch03-immutable-data.md +1122 -0
- package/lib/assets/docs/article/grokkingfp/all/part-2-ch04-higher-order-functions.md +1104 -0
- package/lib/assets/docs/article/grokkingfp/all/part-2-ch05-flatmap.md +1026 -0
- package/lib/assets/docs/article/grokkingfp/all/part-3-ch06-option.md +777 -0
- package/lib/assets/docs/article/grokkingfp/all/part-3-ch07-either-adt.md +871 -0
- package/lib/assets/docs/article/grokkingfp/all/part-4-ch08-io-monad.md +972 -0
- package/lib/assets/docs/article/grokkingfp/all/part-4-ch09-streams.md +926 -0
- package/lib/assets/docs/article/grokkingfp/all/part-5-ch10-concurrency.md +870 -0
- package/lib/assets/docs/article/grokkingfp/all/part-6-ch11-application.md +715 -0
- package/lib/assets/docs/article/grokkingfp/all/part-6-ch12-testing.md +626 -0
- package/lib/assets/docs/article/grokkingfp/all/writing-plan.md +696 -0
- package/lib/assets/docs/article/grokkingfp/clojure/index.md +276 -0
- package/lib/assets/docs/article/grokkingfp/clojure/part-1.md +667 -0
- package/lib/assets/docs/article/grokkingfp/clojure/part-2.md +643 -0
- package/lib/assets/docs/article/grokkingfp/clojure/part-3.md +620 -0
- package/lib/assets/docs/article/grokkingfp/clojure/part-4.md +697 -0
- package/lib/assets/docs/article/grokkingfp/clojure/part-5.md +751 -0
- package/lib/assets/docs/article/grokkingfp/clojure/part-6.md +721 -0
- package/lib/assets/docs/article/grokkingfp/csharp/index.md +246 -0
- package/lib/assets/docs/article/grokkingfp/csharp/part-1.md +811 -0
- package/lib/assets/docs/article/grokkingfp/csharp/part-2.md +971 -0
- package/lib/assets/docs/article/grokkingfp/csharp/part-3.md +981 -0
- package/lib/assets/docs/article/grokkingfp/csharp/part-4.md +949 -0
- package/lib/assets/docs/article/grokkingfp/csharp/part-5.md +947 -0
- package/lib/assets/docs/article/grokkingfp/csharp/part-6.md +739 -0
- package/lib/assets/docs/article/grokkingfp/elixir/index.md +203 -0
- package/lib/assets/docs/article/grokkingfp/elixir/part-1.md +710 -0
- package/lib/assets/docs/article/grokkingfp/elixir/part-2.md +838 -0
- package/lib/assets/docs/article/grokkingfp/elixir/part-3.md +985 -0
- package/lib/assets/docs/article/grokkingfp/elixir/part-4.md +974 -0
- package/lib/assets/docs/article/grokkingfp/elixir/part-5.md +1284 -0
- package/lib/assets/docs/article/grokkingfp/elixir/part-6.md +1047 -0
- package/lib/assets/docs/article/grokkingfp/fsharp/index.md +210 -0
- package/lib/assets/docs/article/grokkingfp/fsharp/part-1.md +714 -0
- package/lib/assets/docs/article/grokkingfp/fsharp/part-2.md +961 -0
- package/lib/assets/docs/article/grokkingfp/fsharp/part-3.md +972 -0
- package/lib/assets/docs/article/grokkingfp/fsharp/part-4.md +832 -0
- package/lib/assets/docs/article/grokkingfp/fsharp/part-5.md +911 -0
- package/lib/assets/docs/article/grokkingfp/fsharp/part-6.md +920 -0
- package/lib/assets/docs/article/grokkingfp/haskell/index.md +234 -0
- package/lib/assets/docs/article/grokkingfp/haskell/part-1.md +591 -0
- package/lib/assets/docs/article/grokkingfp/haskell/part-2.md +866 -0
- package/lib/assets/docs/article/grokkingfp/haskell/part-3.md +915 -0
- package/lib/assets/docs/article/grokkingfp/haskell/part-4.md +876 -0
- package/lib/assets/docs/article/grokkingfp/haskell/part-5.md +845 -0
- package/lib/assets/docs/article/grokkingfp/haskell/part-6.md +842 -0
- package/lib/assets/docs/article/grokkingfp/index.md +143 -0
- package/lib/assets/docs/article/grokkingfp/java/index.md +211 -0
- package/lib/assets/docs/article/grokkingfp/java/part-1.md +646 -0
- package/lib/assets/docs/article/grokkingfp/java/part-2.md +667 -0
- package/lib/assets/docs/article/grokkingfp/java/part-3.md +672 -0
- package/lib/assets/docs/article/grokkingfp/java/part-4.md +771 -0
- package/lib/assets/docs/article/grokkingfp/java/part-5.md +959 -0
- package/lib/assets/docs/article/grokkingfp/java/part-6.md +1324 -0
- package/lib/assets/docs/article/grokkingfp/python/index.md +258 -0
- package/lib/assets/docs/article/grokkingfp/python/part-1.md +437 -0
- package/lib/assets/docs/article/grokkingfp/python/part-2.md +958 -0
- package/lib/assets/docs/article/grokkingfp/python/part-3.md +1004 -0
- package/lib/assets/docs/article/grokkingfp/python/part-4.md +765 -0
- package/lib/assets/docs/article/grokkingfp/python/part-5.md +747 -0
- package/lib/assets/docs/article/grokkingfp/python/part-6.md +861 -0
- package/lib/assets/docs/article/grokkingfp/ruby/index.md +330 -0
- package/lib/assets/docs/article/grokkingfp/ruby/part-1.md +753 -0
- package/lib/assets/docs/article/grokkingfp/ruby/part-2.md +938 -0
- package/lib/assets/docs/article/grokkingfp/ruby/part-3.md +946 -0
- package/lib/assets/docs/article/grokkingfp/ruby/part-4.md +921 -0
- package/lib/assets/docs/article/grokkingfp/ruby/part-5.md +908 -0
- package/lib/assets/docs/article/grokkingfp/ruby/part-6.md +1410 -0
- package/lib/assets/docs/article/grokkingfp/rust/index.md +242 -0
- package/lib/assets/docs/article/grokkingfp/rust/part-1.md +634 -0
- package/lib/assets/docs/article/grokkingfp/rust/part-2.md +1060 -0
- package/lib/assets/docs/article/grokkingfp/rust/part-3.md +994 -0
- package/lib/assets/docs/article/grokkingfp/rust/part-4.md +571 -0
- package/lib/assets/docs/article/grokkingfp/rust/part-5.md +705 -0
- package/lib/assets/docs/article/grokkingfp/rust/part-6.md +508 -0
- package/lib/assets/docs/article/grokkingfp/scala/index.md +171 -0
- package/lib/assets/docs/article/grokkingfp/scala/part-1.md +541 -0
- package/lib/assets/docs/article/grokkingfp/scala/part-2.md +946 -0
- package/lib/assets/docs/article/grokkingfp/scala/part-3.md +917 -0
- package/lib/assets/docs/article/grokkingfp/scala/part-4.md +742 -0
- package/lib/assets/docs/article/grokkingfp/scala/part-5.md +722 -0
- package/lib/assets/docs/article/grokkingfp/scala/part-6.md +865 -0
- package/lib/assets/docs/article/grokkingfp/typescript/index.md +273 -0
- package/lib/assets/docs/article/grokkingfp/typescript/part-1.md +559 -0
- package/lib/assets/docs/article/grokkingfp/typescript/part-2.md +1129 -0
- package/lib/assets/docs/article/grokkingfp/typescript/part-3.md +842 -0
- package/lib/assets/docs/article/grokkingfp/typescript/part-4.md +1085 -0
- package/lib/assets/docs/article/grokkingfp/typescript/part-5.md +717 -0
- package/lib/assets/docs/article/grokkingfp/typescript/part-6.md +980 -0
- package/lib/assets/docs/article/index.md +36 -0
- package/lib/assets/docs/design/index.md +39 -27
- package/lib/assets/docs/development/index.md +11 -1
- package/lib/assets/docs/index.md +33 -106
- package/lib/assets/docs/operation/index.md +16 -6
- package/lib/assets/docs/reference/index.md +5 -4
- package/lib/assets/docs/requirements/index.md +13 -6
- package/lib/assets/docs/strategy/index.md +11 -4
- package/lib/assets/docs/template/index.md +9 -5
- package/lib/assets/mkdocs.yml +29 -17
- package/package.json +1 -1
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
# 第 6 章: タスクランナーと CI/CD
|
|
2
|
+
|
|
3
|
+
## 6.1 はじめに
|
|
4
|
+
|
|
5
|
+
前章では静的コード解析ツールとコードフォーマッターを導入しました。テストの実行、静的解析、フォーマットチェックと、様々なコマンドを使えるようになりましたが、毎回それぞれのコマンドを覚えて実行するのは面倒です。
|
|
6
|
+
|
|
7
|
+
この章では **タスクランナー** を使ってこれらのタスクをまとめて実行できるようにし、さらに **CI/CD** パイプラインを構築します。
|
|
8
|
+
|
|
9
|
+
## 6.2 Cake によるタスク管理
|
|
10
|
+
|
|
11
|
+
### Cake とは
|
|
12
|
+
|
|
13
|
+
> Cake (C# Make) は C# の DSL で記述するクロスプラットフォームのビルドオーケストレーションツールです。ビルド、テスト、デプロイなどのタスクを C# のコードで定義できます。
|
|
14
|
+
|
|
15
|
+
Ruby の Rake、Java の Gradle、Rust の Makefile に相当します。C# 開発者にとっては、使い慣れた C# 構文でタスクを定義できるのが利点です。
|
|
16
|
+
|
|
17
|
+
### Cake のインストール
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
# グローバルツールとしてインストール
|
|
21
|
+
$ dotnet tool install -g Cake.Tool
|
|
22
|
+
|
|
23
|
+
# またはローカルツールとして
|
|
24
|
+
$ dotnet new tool-manifest
|
|
25
|
+
$ dotnet tool install Cake.Tool
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### build.cake の定義
|
|
29
|
+
|
|
30
|
+
```csharp
|
|
31
|
+
var target = Argument("target", "Default");
|
|
32
|
+
|
|
33
|
+
Task("Clean")
|
|
34
|
+
.Does(() =>
|
|
35
|
+
{
|
|
36
|
+
DotNetClean(".");
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
Task("Restore")
|
|
40
|
+
.Does(() =>
|
|
41
|
+
{
|
|
42
|
+
DotNetRestore(".");
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
Task("Build")
|
|
46
|
+
.IsDependentOn("Restore")
|
|
47
|
+
.Does(() =>
|
|
48
|
+
{
|
|
49
|
+
DotNetBuild(".", new DotNetBuildSettings
|
|
50
|
+
{
|
|
51
|
+
NoRestore = true
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
Task("Test")
|
|
56
|
+
.IsDependentOn("Build")
|
|
57
|
+
.Does(() =>
|
|
58
|
+
{
|
|
59
|
+
DotNetTest(".", new DotNetTestSettings
|
|
60
|
+
{
|
|
61
|
+
NoRestore = true,
|
|
62
|
+
NoBuild = true
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
Task("Format-Check")
|
|
67
|
+
.Does(() =>
|
|
68
|
+
{
|
|
69
|
+
DotNetTool("dotnet format --verify-no-changes");
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
Task("Check")
|
|
73
|
+
.IsDependentOn("Format-Check")
|
|
74
|
+
.IsDependentOn("Build")
|
|
75
|
+
.IsDependentOn("Test");
|
|
76
|
+
|
|
77
|
+
Task("Default")
|
|
78
|
+
.IsDependentOn("Check");
|
|
79
|
+
|
|
80
|
+
RunTarget(target);
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### 主要なタスク
|
|
84
|
+
|
|
85
|
+
| タスク | コマンド | 説明 |
|
|
86
|
+
|--------|---------|------|
|
|
87
|
+
| `dotnet cake --target=Test` | Build → Test | テスト実行 |
|
|
88
|
+
| `dotnet cake --target=Format-Check` | dotnet format --verify-no-changes | フォーマットチェック |
|
|
89
|
+
| `dotnet cake --target=Check` | Format-Check → Build → Test | 全チェック実行 |
|
|
90
|
+
| `dotnet cake --target=Clean` | dotnet clean | ビルド成果物の削除 |
|
|
91
|
+
| `dotnet cake` | Default (= Check) | デフォルトタスク |
|
|
92
|
+
|
|
93
|
+
### 実行例
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
# 全チェック実行
|
|
97
|
+
$ dotnet cake
|
|
98
|
+
========================================
|
|
99
|
+
Format-Check
|
|
100
|
+
========================================
|
|
101
|
+
========================================
|
|
102
|
+
Build
|
|
103
|
+
========================================
|
|
104
|
+
========================================
|
|
105
|
+
Test
|
|
106
|
+
========================================
|
|
107
|
+
成功! -失敗: 0、合格: 7、スキップ: 0
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## 6.3 GitHub Actions による CI/CD
|
|
111
|
+
|
|
112
|
+
### CI/CD とは
|
|
113
|
+
|
|
114
|
+
> CI/CD(Continuous Integration / Continuous Delivery)は、コードの変更を自動的にビルド、テスト、デプロイするプラクティスです。
|
|
115
|
+
|
|
116
|
+
### ワークフローの定義
|
|
117
|
+
|
|
118
|
+
`.github/workflows/dotnet-ci.yml` にワークフローを定義します。
|
|
119
|
+
|
|
120
|
+
```yaml
|
|
121
|
+
name: .NET CI
|
|
122
|
+
|
|
123
|
+
on:
|
|
124
|
+
push:
|
|
125
|
+
branches: [main, develop]
|
|
126
|
+
paths:
|
|
127
|
+
- "apps/dotnet/**"
|
|
128
|
+
- ".github/workflows/dotnet-ci.yml"
|
|
129
|
+
pull_request:
|
|
130
|
+
branches: [main]
|
|
131
|
+
paths:
|
|
132
|
+
- "apps/dotnet/**"
|
|
133
|
+
|
|
134
|
+
permissions:
|
|
135
|
+
contents: read
|
|
136
|
+
|
|
137
|
+
jobs:
|
|
138
|
+
test:
|
|
139
|
+
runs-on: ubuntu-latest
|
|
140
|
+
|
|
141
|
+
steps:
|
|
142
|
+
- name: Checkout the repository
|
|
143
|
+
uses: actions/checkout@v4
|
|
144
|
+
|
|
145
|
+
- name: Setup .NET
|
|
146
|
+
uses: actions/setup-dotnet@v4
|
|
147
|
+
with:
|
|
148
|
+
dotnet-version: '8.0.x'
|
|
149
|
+
|
|
150
|
+
- name: Restore dependencies
|
|
151
|
+
run: dotnet restore
|
|
152
|
+
working-directory: apps/dotnet
|
|
153
|
+
|
|
154
|
+
- name: Check formatting
|
|
155
|
+
run: dotnet format --verify-no-changes
|
|
156
|
+
working-directory: apps/dotnet
|
|
157
|
+
|
|
158
|
+
- name: Build
|
|
159
|
+
run: dotnet build --no-restore
|
|
160
|
+
working-directory: apps/dotnet
|
|
161
|
+
|
|
162
|
+
- name: Run tests
|
|
163
|
+
run: dotnet test --no-build
|
|
164
|
+
working-directory: apps/dotnet
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### CI パイプラインの流れ
|
|
168
|
+
|
|
169
|
+
```
|
|
170
|
+
Push / PR → restore → format --verify-no-changes → build → test → 結果通知
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
## 6.4 他言語との比較
|
|
174
|
+
|
|
175
|
+
| 言語 | タスクランナー | CI ツール | テスト | 静的解析 | フォーマット |
|
|
176
|
+
|------|-------------|----------|--------|---------|------------|
|
|
177
|
+
| C# | Cake | GitHub Actions | xUnit | Roslyn Analyzers | dotnet format |
|
|
178
|
+
| Rust | Makefile | GitHub Actions | cargo test | Clippy | rustfmt |
|
|
179
|
+
| Go | Makefile | GitHub Actions | go test | golangci-lint | gofmt |
|
|
180
|
+
| Java | Gradle | GitHub Actions | JUnit | Checkstyle + PMD | Checkstyle |
|
|
181
|
+
| Python | tox | GitHub Actions | pytest | Ruff | Ruff |
|
|
182
|
+
| Node | npm scripts | GitHub Actions | Vitest | ESLint | Prettier |
|
|
183
|
+
|
|
184
|
+
## 6.5 まとめ
|
|
185
|
+
|
|
186
|
+
この章では以下を実現しました。
|
|
187
|
+
|
|
188
|
+
| 項目 | 内容 |
|
|
189
|
+
|------|------|
|
|
190
|
+
| Cake | Build / Test / Format-Check / Check タスクを定義 |
|
|
191
|
+
| `dotnet cake` | フォーマットチェック → ビルド → テストを一括実行 |
|
|
192
|
+
| GitHub Actions | push / PR 時に自動で CI を実行 |
|
|
193
|
+
| .NET SDK 統合 | CI でも `dotnet` コマンドで環境を統一 |
|
|
194
|
+
|
|
195
|
+
第 2 部を通じて、ソフトウェア開発の三種の神器(バージョン管理、テスティング、自動化)を C# の開発環境に整備しました。次の第 3 部では、オブジェクト指向設計(class、interface、デザインパターン)に進みます。
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
# 第 7 章: カプセル化とポリモーフィズム
|
|
2
|
+
|
|
3
|
+
## 7.1 はじめに
|
|
4
|
+
|
|
5
|
+
第 1 部では手続き型の FizzBuzz プログラムを TDD で構築しました。この章からは **オブジェクト指向プログラミング** の要素を C# で実現していきます。まず **カプセル化** と **ポリモーフィズム** を導入し、手続き型コードを構造化された設計に進化させます。
|
|
6
|
+
|
|
7
|
+
## 7.2 手続き型コードの課題
|
|
8
|
+
|
|
9
|
+
第 1 部で作成した `Generate` メソッドは手続き型プログラミングの典型例です。
|
|
10
|
+
|
|
11
|
+
```csharp
|
|
12
|
+
public static string Generate(int number)
|
|
13
|
+
{
|
|
14
|
+
if (number % 3 == 0 && number % 5 == 0) return "FizzBuzz";
|
|
15
|
+
if (number % 3 == 0) return "Fizz";
|
|
16
|
+
if (number % 5 == 0) return "Buzz";
|
|
17
|
+
return number.ToString();
|
|
18
|
+
}
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
この設計の課題は、新しい FizzBuzz タイプ(数値のみ返す、FizzBuzz のみ返す等)を追加する場合に、既存のメソッドを直接修正する必要があることです。
|
|
22
|
+
|
|
23
|
+
## 7.3 カプセル化 — 値オブジェクトの導入
|
|
24
|
+
|
|
25
|
+
### FizzBuzzValue クラス
|
|
26
|
+
|
|
27
|
+
数値と FizzBuzz の結果をまとめた値オブジェクトを作成します。
|
|
28
|
+
|
|
29
|
+
```csharp
|
|
30
|
+
namespace FizzBuzz.Domain.Model;
|
|
31
|
+
|
|
32
|
+
public class FizzBuzzValue : IEquatable<FizzBuzzValue>
|
|
33
|
+
{
|
|
34
|
+
public int Number { get; }
|
|
35
|
+
public string Value { get; }
|
|
36
|
+
|
|
37
|
+
public FizzBuzzValue(int number, string value)
|
|
38
|
+
{
|
|
39
|
+
Number = number;
|
|
40
|
+
Value = value;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
public override string ToString() => $"{Number}:{Value}";
|
|
44
|
+
|
|
45
|
+
public bool Equals(FizzBuzzValue? other)
|
|
46
|
+
{
|
|
47
|
+
if (other is null) return false;
|
|
48
|
+
if (ReferenceEquals(this, other)) return true;
|
|
49
|
+
return Number == other.Number && Value == other.Value;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
public override bool Equals(object? obj) => Equals(obj as FizzBuzzValue);
|
|
53
|
+
public override int GetHashCode() => HashCode.Combine(Number, Value);
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
C# ではプロパティ(`{ get; }` のみの読み取り専用プロパティ)でフィールドをカプセル化します。`IEquatable<T>` インターフェースを実装して値の等価性を保証します。Rust の `#[derive(PartialEq)]` に相当する機能ですが、C# では手動で実装する必要があります。
|
|
58
|
+
|
|
59
|
+
### テストの作成
|
|
60
|
+
|
|
61
|
+
```csharp
|
|
62
|
+
public class FizzBuzzValueTest
|
|
63
|
+
{
|
|
64
|
+
[Fact]
|
|
65
|
+
public void 値を保持する()
|
|
66
|
+
{
|
|
67
|
+
var value = new FizzBuzzValue(1, "1");
|
|
68
|
+
Assert.Equal(1, value.Number);
|
|
69
|
+
Assert.Equal("1", value.Value);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
[Fact]
|
|
73
|
+
public void 同じ値のオブジェクトは等しい()
|
|
74
|
+
{
|
|
75
|
+
var value1 = new FizzBuzzValue(1, "1");
|
|
76
|
+
var value2 = new FizzBuzzValue(1, "1");
|
|
77
|
+
Assert.Equal(value1, value2);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## 7.4 ポリモーフィズム — interface の導入
|
|
83
|
+
|
|
84
|
+
### IFizzBuzzType インターフェース
|
|
85
|
+
|
|
86
|
+
FizzBuzz のタイプを抽象化するインターフェースを定義します。
|
|
87
|
+
|
|
88
|
+
```csharp
|
|
89
|
+
namespace FizzBuzz.Domain.Type;
|
|
90
|
+
|
|
91
|
+
using FizzBuzz.Domain.Model;
|
|
92
|
+
|
|
93
|
+
public interface IFizzBuzzType
|
|
94
|
+
{
|
|
95
|
+
FizzBuzzValue Generate(int number);
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
C# の `interface` は Rust の `trait` や Java の `interface` に相当します。実装クラスは明示的に `: IFizzBuzzType` と宣言してインターフェースを実装します。
|
|
100
|
+
|
|
101
|
+
### 3 つの実装
|
|
102
|
+
|
|
103
|
+
```csharp
|
|
104
|
+
// タイプ 1: 通常の FizzBuzz
|
|
105
|
+
public class FizzBuzzType01 : IFizzBuzzType
|
|
106
|
+
{
|
|
107
|
+
private const int FizzNumber = 3;
|
|
108
|
+
private const int BuzzNumber = 5;
|
|
109
|
+
|
|
110
|
+
public FizzBuzzValue Generate(int number)
|
|
111
|
+
{
|
|
112
|
+
string value;
|
|
113
|
+
if (IsFizzBuzz(number)) value = "FizzBuzz";
|
|
114
|
+
else if (IsFizz(number)) value = "Fizz";
|
|
115
|
+
else if (IsBuzz(number)) value = "Buzz";
|
|
116
|
+
else value = number.ToString();
|
|
117
|
+
|
|
118
|
+
return new FizzBuzzValue(number, value);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
private static bool IsFizz(int number) => number % FizzNumber == 0;
|
|
122
|
+
private static bool IsBuzz(int number) => number % BuzzNumber == 0;
|
|
123
|
+
private static bool IsFizzBuzz(int number) => IsFizz(number) && IsBuzz(number);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// タイプ 2: 数値のみ
|
|
127
|
+
public class FizzBuzzType02 : IFizzBuzzType
|
|
128
|
+
{
|
|
129
|
+
public FizzBuzzValue Generate(int number)
|
|
130
|
+
{
|
|
131
|
+
return new FizzBuzzValue(number, number.ToString());
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// タイプ 3: 15 の倍数のみ FizzBuzz
|
|
136
|
+
public class FizzBuzzType03 : IFizzBuzzType
|
|
137
|
+
{
|
|
138
|
+
private const int FizzBuzzNumber = 15;
|
|
139
|
+
|
|
140
|
+
public FizzBuzzValue Generate(int number)
|
|
141
|
+
{
|
|
142
|
+
var value = number % FizzBuzzNumber == 0 ? "FizzBuzz" : number.ToString();
|
|
143
|
+
return new FizzBuzzValue(number, value);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### テストの作成
|
|
149
|
+
|
|
150
|
+
```csharp
|
|
151
|
+
public class FizzBuzzType01Test
|
|
152
|
+
{
|
|
153
|
+
private readonly IFizzBuzzType _type = new FizzBuzzType01();
|
|
154
|
+
|
|
155
|
+
[Fact]
|
|
156
|
+
public void 数を文字列にして返す()
|
|
157
|
+
{
|
|
158
|
+
Assert.Equal("1", _type.Generate(1).Value);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
[Fact]
|
|
162
|
+
public void 三の倍数のときはFizzを返す()
|
|
163
|
+
{
|
|
164
|
+
Assert.Equal("Fizz", _type.Generate(3).Value);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
[Fact]
|
|
168
|
+
public void 五の倍数のときはBuzzを返す()
|
|
169
|
+
{
|
|
170
|
+
Assert.Equal("Buzz", _type.Generate(5).Value);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
[Fact]
|
|
174
|
+
public void 三と五の倍数のときはFizzBuzzを返す()
|
|
175
|
+
{
|
|
176
|
+
Assert.Equal("FizzBuzz", _type.Generate(15).Value);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
## 7.5 ファクトリメソッド
|
|
182
|
+
|
|
183
|
+
タイプ番号から適切な実装を返すファクトリメソッドを作成します。
|
|
184
|
+
|
|
185
|
+
```csharp
|
|
186
|
+
public static class FizzBuzzTypeFactory
|
|
187
|
+
{
|
|
188
|
+
public static IFizzBuzzType Create(int type)
|
|
189
|
+
{
|
|
190
|
+
return type switch
|
|
191
|
+
{
|
|
192
|
+
1 => new FizzBuzzType01(),
|
|
193
|
+
2 => new FizzBuzzType02(),
|
|
194
|
+
3 => new FizzBuzzType03(),
|
|
195
|
+
_ => throw new ArgumentException($"Invalid FizzBuzz type: {type}")
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
C# の `switch` 式は Rust の `match` 式に近い構文で、値を返す式として使えます。`_` はデフォルトケースで、Rust のワイルドカードパターンと同じです。不正なタイプ番号の場合は `ArgumentException` をスローします。
|
|
202
|
+
|
|
203
|
+
## 7.6 まとめ
|
|
204
|
+
|
|
205
|
+
この章では以下を学びました。
|
|
206
|
+
|
|
207
|
+
| 概念 | C# の実現方法 | 他言語の対応 |
|
|
208
|
+
|------|-------------|-------------|
|
|
209
|
+
| カプセル化 | `class` + 読み取り専用プロパティ | Rust: struct + 非公開フィールド |
|
|
210
|
+
| ポリモーフィズム | `interface` + 明示的実装 | Rust: trait + impl |
|
|
211
|
+
| 値オブジェクト | `IEquatable<T>` + `GetHashCode` | Rust: `#[derive(PartialEq)]` |
|
|
212
|
+
| ファクトリ | `switch` 式 + `ArgumentException` | Rust: `match` + `Result` |
|
|
213
|
+
|
|
214
|
+
次章では、デザインパターン(Command、First-Class Collection)を適用していきます。
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
# 第 8 章: デザインパターンの適用
|
|
2
|
+
|
|
3
|
+
## 8.1 はじめに
|
|
4
|
+
|
|
5
|
+
前章では class と interface を使ってカプセル化とポリモーフィズムを実現しました。この章では **デザインパターン** を適用して、設計をさらに改善します。
|
|
6
|
+
|
|
7
|
+
## 8.2 Value Object パターン
|
|
8
|
+
|
|
9
|
+
### FizzBuzzValue の強化
|
|
10
|
+
|
|
11
|
+
前章で作成した `FizzBuzzValue` は既に Value Object パターンを実現しています。
|
|
12
|
+
|
|
13
|
+
```csharp
|
|
14
|
+
public class FizzBuzzValue : IEquatable<FizzBuzzValue>
|
|
15
|
+
{
|
|
16
|
+
public int Number { get; }
|
|
17
|
+
public string Value { get; }
|
|
18
|
+
|
|
19
|
+
public FizzBuzzValue(int number, string value)
|
|
20
|
+
{
|
|
21
|
+
Number = number;
|
|
22
|
+
Value = value;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
public override string ToString() => $"{Number}:{Value}";
|
|
26
|
+
|
|
27
|
+
public bool Equals(FizzBuzzValue? other)
|
|
28
|
+
{
|
|
29
|
+
if (other is null) return false;
|
|
30
|
+
if (ReferenceEquals(this, other)) return true;
|
|
31
|
+
return Number == other.Number && Value == other.Value;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
public override bool Equals(object? obj) => Equals(obj as FizzBuzzValue);
|
|
35
|
+
public override int GetHashCode() => HashCode.Combine(Number, Value);
|
|
36
|
+
}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
`IEquatable<T>` の実装により、2 つの `FizzBuzzValue` を値で比較できます。読み取り専用プロパティにより不変性が保証されます。Rust の `#[derive(PartialEq, Clone)]` に対し、C# では `IEquatable<T>` と `GetHashCode` を明示的に実装します。
|
|
40
|
+
|
|
41
|
+
## 8.3 First-Class Collection パターン
|
|
42
|
+
|
|
43
|
+
### FizzBuzzList クラス
|
|
44
|
+
|
|
45
|
+
FizzBuzzValue のコレクションを専用の型でラップします。
|
|
46
|
+
|
|
47
|
+
```csharp
|
|
48
|
+
namespace FizzBuzz.Domain.Model;
|
|
49
|
+
|
|
50
|
+
public class FizzBuzzList : IEquatable<FizzBuzzList>
|
|
51
|
+
{
|
|
52
|
+
private readonly List<FizzBuzzValue> _values;
|
|
53
|
+
|
|
54
|
+
public IReadOnlyList<FizzBuzzValue> Values => _values.AsReadOnly();
|
|
55
|
+
|
|
56
|
+
public FizzBuzzList()
|
|
57
|
+
{
|
|
58
|
+
_values = new List<FizzBuzzValue>();
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
public FizzBuzzList(List<FizzBuzzValue> values)
|
|
62
|
+
{
|
|
63
|
+
_values = new List<FizzBuzzValue>(values);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
public FizzBuzzValue Get(int index) => _values[index];
|
|
67
|
+
public int Count => _values.Count;
|
|
68
|
+
|
|
69
|
+
public FizzBuzzList Add(FizzBuzzValue value)
|
|
70
|
+
{
|
|
71
|
+
var newValues = new List<FizzBuzzValue>(_values) { value };
|
|
72
|
+
return new FizzBuzzList(newValues);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
public List<string> ToStringValues()
|
|
76
|
+
{
|
|
77
|
+
return _values.Select(v => v.Value).ToList();
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// ...等価性の実装
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
First-Class Collection パターンにより、コレクション操作の責務を `FizzBuzzList` に集約できます。`Add` メソッドは新しいリストを返すイミュータブルな設計です。`IReadOnlyList<T>` で公開することで外部からの変更を防ぎます。
|
|
85
|
+
|
|
86
|
+
### テストの作成
|
|
87
|
+
|
|
88
|
+
```csharp
|
|
89
|
+
public class FizzBuzzListTest
|
|
90
|
+
{
|
|
91
|
+
[Fact]
|
|
92
|
+
public void 空のリストを作成できる()
|
|
93
|
+
{
|
|
94
|
+
var list = new FizzBuzzList();
|
|
95
|
+
Assert.Equal(0, list.Count);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
[Fact]
|
|
99
|
+
public void 値を追加できる()
|
|
100
|
+
{
|
|
101
|
+
var list = new FizzBuzzList();
|
|
102
|
+
var newList = list.Add(new FizzBuzzValue(1, "1"));
|
|
103
|
+
Assert.Equal(1, newList.Count);
|
|
104
|
+
Assert.Equal(0, list.Count); // 元のリストは変更されない
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
[Fact]
|
|
108
|
+
public void 文字列リストに変換できる()
|
|
109
|
+
{
|
|
110
|
+
var list = new FizzBuzzList(new List<FizzBuzzValue>
|
|
111
|
+
{
|
|
112
|
+
new FizzBuzzValue(1, "1"),
|
|
113
|
+
new FizzBuzzValue(3, "Fizz"),
|
|
114
|
+
new FizzBuzzValue(5, "Buzz")
|
|
115
|
+
});
|
|
116
|
+
var strings = list.ToStringValues();
|
|
117
|
+
Assert.Equal(new List<string> { "1", "Fizz", "Buzz" }, strings);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## 8.4 Command パターン
|
|
123
|
+
|
|
124
|
+
### IFizzBuzzCommand インターフェース
|
|
125
|
+
|
|
126
|
+
FizzBuzz の操作をコマンドとして抽象化します。
|
|
127
|
+
|
|
128
|
+
```csharp
|
|
129
|
+
namespace FizzBuzz.Application;
|
|
130
|
+
|
|
131
|
+
using FizzBuzz.Domain.Model;
|
|
132
|
+
|
|
133
|
+
public interface IFizzBuzzCommand
|
|
134
|
+
{
|
|
135
|
+
FizzBuzzValue ExecuteValue(int number);
|
|
136
|
+
FizzBuzzList ExecuteList(int count);
|
|
137
|
+
}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### 単一値コマンド
|
|
141
|
+
|
|
142
|
+
```csharp
|
|
143
|
+
public class FizzBuzzValueCommand : IFizzBuzzCommand
|
|
144
|
+
{
|
|
145
|
+
private readonly IFizzBuzzType _type;
|
|
146
|
+
|
|
147
|
+
public FizzBuzzValueCommand(IFizzBuzzType type)
|
|
148
|
+
{
|
|
149
|
+
_type = type;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
public FizzBuzzValue ExecuteValue(int number)
|
|
153
|
+
{
|
|
154
|
+
return _type.Generate(number);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
public FizzBuzzList ExecuteList(int count)
|
|
158
|
+
{
|
|
159
|
+
throw new NotSupportedException(
|
|
160
|
+
"FizzBuzzValueCommand does not support list execution.");
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### リストコマンド
|
|
166
|
+
|
|
167
|
+
```csharp
|
|
168
|
+
public class FizzBuzzListCommand : IFizzBuzzCommand
|
|
169
|
+
{
|
|
170
|
+
private readonly IFizzBuzzType _type;
|
|
171
|
+
|
|
172
|
+
public FizzBuzzListCommand(IFizzBuzzType type)
|
|
173
|
+
{
|
|
174
|
+
_type = type;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
public FizzBuzzValue ExecuteValue(int number)
|
|
178
|
+
{
|
|
179
|
+
throw new NotSupportedException(
|
|
180
|
+
"FizzBuzzListCommand does not support single value execution.");
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
public FizzBuzzList ExecuteList(int count)
|
|
184
|
+
{
|
|
185
|
+
var values = Enumerable.Range(1, count)
|
|
186
|
+
.Select(i => _type.Generate(i))
|
|
187
|
+
.ToList();
|
|
188
|
+
return new FizzBuzzList(values);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
コンストラクタインジェクションで `IFizzBuzzType` を受け取ることで、具体的なタイプに依存しない設計を実現しています。
|
|
194
|
+
|
|
195
|
+
### テストの作成
|
|
196
|
+
|
|
197
|
+
```csharp
|
|
198
|
+
public class FizzBuzzCommandTest
|
|
199
|
+
{
|
|
200
|
+
[Fact]
|
|
201
|
+
public void ValueCommandで単一値を取得できる()
|
|
202
|
+
{
|
|
203
|
+
var command = new FizzBuzzValueCommand(
|
|
204
|
+
FizzBuzzTypeFactory.Create(FizzBuzzTypeName.Standard));
|
|
205
|
+
var result = command.ExecuteValue(3);
|
|
206
|
+
Assert.Equal("Fizz", result.Value);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
[Fact]
|
|
210
|
+
public void ListCommandでリストを生成できる()
|
|
211
|
+
{
|
|
212
|
+
var command = new FizzBuzzListCommand(
|
|
213
|
+
FizzBuzzTypeFactory.Create(FizzBuzzTypeName.Standard));
|
|
214
|
+
var result = command.ExecuteList(100);
|
|
215
|
+
Assert.Equal(100, result.Count);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
## 8.5 Strategy パターン
|
|
221
|
+
|
|
222
|
+
`IFizzBuzzType` インターフェースと 3 つの実装クラス(`FizzBuzzType01`, `FizzBuzzType02`, `FizzBuzzType03`)は、Strategy パターンを実現しています。コマンドのコンストラクタに異なる `IFizzBuzzType` を渡すことで、同じインターフェースで異なる振る舞いを切り替えられます。
|
|
223
|
+
|
|
224
|
+
### Factory Method パターン
|
|
225
|
+
|
|
226
|
+
`FizzBuzzTypeFactory.Create` メソッドは Factory Method パターンです。
|
|
227
|
+
|
|
228
|
+
```csharp
|
|
229
|
+
public static IFizzBuzzType Create(FizzBuzzTypeName name)
|
|
230
|
+
{
|
|
231
|
+
return Create((int)name);
|
|
232
|
+
}
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
`FizzBuzzTypeName` enum を使うことで、型安全なファクトリ呼び出しが可能です。
|
|
236
|
+
|
|
237
|
+
## 8.6 まとめ
|
|
238
|
+
|
|
239
|
+
この章では以下のデザインパターンを適用しました。
|
|
240
|
+
|
|
241
|
+
| パターン | 目的 | C# の実現方法 |
|
|
242
|
+
|---------|------|-------------|
|
|
243
|
+
| Value Object | 値の等価性保証 | `IEquatable<T>` + 読み取り専用プロパティ |
|
|
244
|
+
| First-Class Collection | コレクション操作の集約 | `class` + `List<T>` + `IReadOnlyList<T>` |
|
|
245
|
+
| Command | 操作の抽象化と遅延実行 | `interface` + コンストラクタインジェクション |
|
|
246
|
+
| Strategy | アルゴリズムの交換可能性 | `interface` + 複数の実装クラス |
|
|
247
|
+
| Factory Method | タイプ番号による生成 | `switch` 式 + `static` メソッド |
|
|
248
|
+
|
|
249
|
+
次章では SOLID 原則の観点から設計を評価し、モジュール分割を行います。
|