DDDを実践し始めてまだ日が浅いので、ドメインモデリング中に
細かい原則がすぐ出てこなくて迷うことがあります。
そこで、「エリック・エヴァンスのドメイン駆動設計」から
第2部「モデル駆動設計の構成要素」を中心に、モデルを表現する各要素(パターン)の
基本原則をまとめてみます。
第5章「ソフトウェアで表現されたモデル」
- 関連
- ENTITIES(エンティティ)
- VALUE OBJECTS(値オブジェクト)
- SERVICES(サービス)
- MODULES(モジュール)
第6章「ドメインオブジェクトのライフサイクル」
- AGGREGATES(集約)
- FACTORIES(ファクトリ)
- REPOSITORIES(リポジトリ)
関連
- 関連をたどる方向を強制する
- 限定子を付けて多重度を減らす
- ドメインにとって本質的でない関連を除去する
- 本質的でない関連が除去された結果、残った関連はそのドメインの特徴を表す
ENTITIES(エンティティ)
- 属性と振る舞いを本当に必要なものだけにして、小さく保つ
- 不変な値オブジェクトの識別子で別のオブジェクトと比較する
VALUE OBJECTS(値オブジェクト)
- エンティティの属性として使用される
- 他の値オブジェクトの属性として使用される
- エンティティを参照することができる
- 値を共有しないことを前提に、可変な実装にしてもよい場合がある(ほとんどないはず)
SERVICES(サービス)
- エンティティや値オブジェクトの自然な責務とならないものを担当する
- 操作がドメインの概念に関係している
- 他のドメインモデルの観点からインタフェースが定義されている
- 自身の振る舞いに影響を与える状態は存在しない
- 操作名が必ずユビキタス言語の一部になる
- インフラストラクチャサービスと区別する
- アプリケーションサービスと区別する(見分けにくい場合があるので注意)
- 中粒度の機能を提供する(細かすぎるとアプリケーション層にドメインの知識が漏れる)
MODULES(モジュール)
- 大まかなドメインの概念に基づいて分類する
- 同じグループの概念を集めてモジュール内を高凝集にする
- 関係性が薄い他のモジュールとは低結合になる
- 設計が大きく複雑になるにつれて重要になってくる
- 「境界づけられたコンテキスト」とは違うので注意
AGGREGATES(集約)
- 集約のメンバはエンティティと値オブジェクトのみ
- 集約内のオブジェクトが1つだけの場合もある
- 集約のルートは、その集約に含まれる特定の1エンティティ
- 集約のルートは、内部のエンティティへの参照を他のオブジェクトへ渡すことはできる(保持はさせない)
- 集約内のオブジェクト同士は参照を保持し合ってもよい
- 集約内のルート以外のエンティティは、集約内でのみ識別するためのローカルな同一性を持つ
- 集約内のオブジェクトは、他の集約ルートへの参照を保持できる
- 削除する時は集約内のオブジェクトを全て削除しなければならない
- 1つの集約内で適用される不変条件は、各トランザクションの完了によって強制される
FACTORIES(ファクトリ)
- 複雑なオブジェクトと集約を生成する
- 集約を生成する時は不変条件を強制する
- エンティティの生成では不変条件を全て満たすが、必須ではない要素が後で追加される可能性はある
- 集約のルートにその集約内のオブジェクトのファクトリメソッドを置く
- 集約の外にあるオブジェクトが、別の集約のエンティティをファクトリメソッドで生成してもよい
- 既存のオブジェクトが生成の自然な責務を負えない場合は、独立した専用ファクトリを作成する
- 専用のファクトリは、オブジェクトかドメインサービスとして実装する
- 専用のファクトリに不変条件のロジックを入れてもよい
- ファクトリメソッドには不変条件のロジックを入れない方がよい(生成したオブジェクトに委譲する)
再構成ファクトリ
- DBのデータなどからオブジェクトを再構成するのもファクトリの仕事
- 新しい追跡IDを割り当ててはいけない
- 不変条件の違反になんらかの対応が必要
REPOSITORIES(リポジトリ)
- 生成と関連をたどる以外の方法でオブジェクトを取得する手段
- 集約内のオブジェクトはリポジトリから取得してはいけない(ルートから関連をたどる)
- グローバルなIDで検索できるようにする
- 集約に含まれる値オブジェクトの属性で検索もできる
- 検索したオブジェクトの数値属性の集計演算もできる
- トランザクションはクライアントが制御する
- オブジェクトの再構成はファクトリに委譲する
- 外部のプロセスからデータベースへ直接アクセスさせない(不変条件に違反する可能性があるため)
- 双方向の関連のうち一つをリポジトリによる検索に置き換えられる場合がある