「ドメイン駆動設計入門」を読んだ
アドカレ6日目〜
この2日設計の本を書いたので、DDDの本を書いていきます。
この本は入門書ということもあり、昨日の良いコード/悪いコードから学ぶ設計入門と被る点もありますが、DDDの要素と実際のコードを繋ぎ込むのにこの2冊はとてもいい本でした。
お気に入り箇所
ドメインモデルとして挙げられていなかった概念を値オブジェクトにすべきかどうかの判断基準として、筆者は「そこにルールが存在しているか」という点と「それ単体で取り扱いたいか」という点を重要視しています。
値オブジェクトについて、何を値オブジェクトにするかの一節です。
プリミティブ型で実装をしないためにも、値オブジェクトやエンティティとして扱うのがいいよねと個人的には思っています。で「そこにルールが存在しているか」については、ドキュメントとして残す価値があるか・コードを説明する時にコード以外にドキュメントや口伝での継承が必要になるかを基準にして考えるといいと思います。
実際本書でも後述でコードのドキュメント性について値オブジェクトの大切さが明言されていますしね。
値オブジェクトを定義するとそういったルールは値オブジェクトに記述され、コードがドキュメントとして機能し始めます。
続いて3章からエンティティについて
エンティティの性質は次のとおりです。・可変である・同じ属性であっても区別される・同一性により区別される
エンティティと値オブジェクトの違いは、可変/普遍・同一性か/等価性かになります。ということで、エンティティは後からデータの加工ができるものになります。
そのため、扱いは慎重にする必要がありライフサイクルが存在しない限り、できるだけ値オブジェクトにする方が安全だと私は考えています。
ドメイン駆動設計で取りざたされるサービスは大きく分けて 2つです。ひとつがドメインのためのサービスで、もうひとつがアプリケーションのためのサービスです。この 2つを混同することは混乱のもとです。その区分けをしっかりとするために前者をドメインサービスと呼び、後者をアプリケーションサービスと呼びます。
昨日の本でも、ドメインと技術は分けて考えた方がいいと記載されています。それを固有名詞で解説してくれています。
アプリケーションサービスは、アプリケーションを動作させるためのロジックでディスパッチャやDB周りのコネクション周りなどを指しています。
ドメインモデル貧血症という言葉いいですね。症例としては、値やエンティティオブジェクトに正しくドメイン知識が反映されずドキュメントとしての実装が行われていない状態のことを指します。
例えばこの連日の本で言われているgetterを使っており、ロジックが外部に漏れるや、ドメインオブジェクトには何でもロジックが書けてしまうためドメインオブジェクトが不要なコードでファットになることが挙げられます。
テストを行うための手間が積み重なると開発者は次第にテストに対して誠実でなくなっていきます。
リポジトリ層についての利点です。リポジトリ層は技術基盤を呼び出す層です。ドメイン→リポジトリ→技術基盤という依存関係にすることで技術基盤を変えた余波をドメインにまで及ばないようできます。
こうすることで、リポジトリをモックにすることでテストコードを簡単に実装できるようになります。また、テストコードではDBではなくメモリを使うことで、DBへのアクセスを減らしテストコードを速くすることもできて幸せになります。
依存関係はオブジェクトを利用するだけで発生するのです。重要なことは依存を避けることではなく、コントロールすることです。
「利用するだけで発生する」の怖いですね。ドメインオブジェクトを返すと、受け取った側は「ドメインオブジェクトが出来ることを出来てしまう」これは記述箇所を増やし、利用箇所を増やすことにつながるのでドメインオブジェクトの利用をいかに減らすかということが重要になってきます。
複雑な道具はその生成過程も複雑です。ともすれば生成過程がある種の知識となります。
ファクトリーパターンについての記述で、「生成を責務としたオブジェクトを作ろう」という話。ドメインが複雑であるならば、実装も複雑にならざるを得ないので責務を分けて個々の複雑性を分解していくのが重要ですね。
もっとも重要なことはドメインの本質に向き合うことです。技術的なパターンは絶対的な答えとして君臨するものではなく、ドメインの本質に向き合い、それをうまくコードで表現するためのサポート役として機能します。
時折批判はされている軽量DDDはパターンのみを反映させたものなので、ドメインという本質に向き合う必要があるので批判されているような感じですね。
ドメインの本質を見ることで何が変化しやすいか、何をオブジェクトにすべきかといった話ができるようになります。