『ドメイン駆動設計入門 - ボトムアップでわかる!ドメイン駆動設計の基本』を読んだ

どんな本か

ドメイン駆動設計についてかなり噛み砕いて説明された本です。

難しく抽象的な説明はあまりなく、具体的なパターンを説明しながらドメイン駆動設計とはどういうものか語られています。

一つの章で一つのパターンが説明されているので読み進めやすく、サンプルコードも豊富に書かれているので具体的なサンプルからなにかヒントを掴みたい人におすすめです。

目次は以下の通り。

  • 1章 ドメイン駆動設計とは
  • 2章 システム固有の値を表現する「値オブジェクト」
  • 3章 ライフサイクルのあるオブジェクト「エンティティ」
  • 4章 不自然さを解決する「ドメインサービス」
  • 5章 データにまつわる処理を分離する「リポジトリ」
  • 6章 ユースケースを実現する「アプリケーションサービス」
  • 7章 柔軟性をもたらす依存関係のコントロール
  • 8章 ソフトウェア・システムを組み立てる
  • 9章 複雑な生成処理を行う「ファクトリ」
  • 10章 データの整合性を保つ
  • 11章 アプリケーションを1から組み立てる
  • 12章 ドメインのルールを守る「集約」
  • 13章 複雑な条件を表現する「仕様」
  • 14章 アーキテクチャ
  • 15章 ドメイン駆動設計のとびらを開こう
  • 付録 ソリューション構成

目的

システムやアプリケーションの設計力をつけて、より継続的に開発しやすく変更にも強いシステムを開発できるようになりたいと思い読み始めました。

ドメイン駆動設計にこだわらないですが、よりシステム設計に関する文書をたくさん読み込むことで、自分が持つパターンを増やして表現しやすくしたいという思いもあります。

感想

ドメイン駆動設計がドメインの知識に焦点をあてて設計する手法で、そのためにドメインやユースケースをどのようにコードで表現するのかが具体的で分かりやすかったです。

一方で、どのようにパッケージを分けるのか、どういうアーキテクチャを採用するとすると良いかに関してはページがあまり割かれておらず、他の本で補完する必要があるなと思いました。

また、エリック・エヴァンスのドメイン駆動設計と実践ドメイン駆動設計も読んで、自分の中で腹落ちするまで時間かける必要がありそうです。

読書ノート

  • ドメイン駆動設計
    • ドメインの知識に焦点を当てた設計手法
  • ドメイン
    • ソフトウェア開発におけるドメインは、「プログラムを適用する対象となる領域」を指す
  • モデル
    • 現実の事象あるいは概念を抽象化した概念
  • ドメインモデル
    • ドメインの概念をモデリングして得られたモデル
  • 値オブジェクト
    • 不変である
    • 交換可能である
    • 等価性によって比較される
    • 独自のふるまいを定義できる
  • エンティティ
    • 可変である
    • 同じ属性であっても区別される
    • 同一性によって区別される
    • ライフサイクルが存在し、そこに連続性が存在するかが判断基準
  • ドメインサービス
    • 値オブジェクトやエンティティに記述すると不自然になるふるまいが存在するが、それを解決するためのオブジェクト
    • 記述するのは「不自然なふるまい」に限定すること
  • ドメイン貧血症
    • ドメインオブジェクトに本来記述されるべき知識や振る舞いがドメインサービスやアプリケーションサービスに記述され、語るべきことを何も語っていないドメインオブジェクトの状態のこと
  • リポジトリ
    • 責務はドメインオブジェクトの永続化や再構築を行うこと
    • 重要なのはインスタンスを何らかの手段によって保存するということ
  • アプリケーションサービス
    • ユースケースを実現するオブジェクト
    • ドメインオブジェクトのふるまいを呼び出す役目を持つ
    • ドメインオブジェクトのタスク調整に徹するべき
    • ドメインのルールは記述されるべきではない
  • 凝集度
    • モジュールの責任範囲がどれだけ集中しているかを測る尺度
    • 凝集度を高めると、モジュールがひとつの事柄に集中することになり、堅牢性・信頼性・再利用性・可読性の観点から好ましい
    • 凝集度を高めるにはクラス分割が簡単な対処法
  • サービス
    • クライアントのために何かを行うもの
    • サービスはものごとではなく、活動や行動であることが多い
    • サービスは自身のふるまいを変化させる目的で状態を保持しない
    • 状態を一切もっていないことを意味しない
      • 自身のふるまいを変化させる目的の状態ではない
  • 依存関係逆転の原則(Dependency Inversion Principle)
    • A: 上位レベルのモジュールは下位レベルのモジュールに依存してはならない、どちらもモジュールも抽象に依存すべきである
    • B: 抽象は、実装の詳細に依存してはならない。実装の称しあは抽象に依存すべきである。
    • 依存の方向を制御し、すべてのモジュールが抽象へ依存するように制御する
  • ファクトリ
    • 求められることは複雑なオブジェクトの生成処理をオブジェクトとして定義すること
    • オブジェクトの生成に関わる地s樹がまとめられたオブジェクト
  • ユニットオブワーク
    • あるオブジェクトの変更を記録するオブジェクト
    • オブジェクトの読み取り動作を行う際にインスタンスの状態を記録する。読み取られたオブジェクトの変更や削除はユニットオブワークにつ打ちしない限りデータストアへ反映されることがない
    • コミット処理が呼び出されると、そこまでの変更処理をデータストアに対して適用する
    • このパターンを適用すると、永続化の対象となるオブジェクトの作成・変更・削除といった動作はすべてユニットオブワークを通じて行うようになる
  • 集約
    • 関連するオブジェクト同士を線で囲う境界として定義される
    • 集約の外部から境界の内部のオブジェクトを操作してはならない
    • 集約を操作するための直接のインターフェースとなるオブジェクトは集約ルート(AR: Aggregate Root)とよばれるオブジェクトに限定される
    • 外部から内部のオブジェクトに対して直接操作するのではなく、そのオブジェクトを保持するオブジェクトに依頼する形を取る
    • 「変更の単位」で集約を区切る
  • 仕様
    • 仕様はあるお部会j区とがある評価基準に達しているかを判定するオブジェクト
    • 値オブジェクトやエンティティにリポジトリを操作させないために取られる手段は仕様と呼ばれるオブジェクトを利用した解決
    • 仕様はれっきとしたドメインオブジェクト