「Application Architecture for .NET」を読んだ - 3部(前編)
.NETのエンタープライズアプリケーションアーキテクチャ 第2版 (マイクロソフト公式解説書)
- 作者: Dino Esposito,Andrea Saltarello,日本マイクロソフト(監訳),クイープ
- 出版社/メーカー: 日経BP社
- 発売日: 2015/06/04
- メディア: 単行本
- この商品を含むブログ (2件) を見る
「Application Architecture for .NET」を読んだ - 1部
「Application Architecture for .NET」を読んだ - 2部
の続き
第三部サポートアーキテクチャ(8, 9章)のメモ。
TL;DL
- ドメインモデル
- エンティティはビジネス空間に関連するオブジェクトであり同一性とライフタイムを持つ
- 値オブジェクトは空間内の無生物とも言える存在
- 一部のエンティティはコーディグや設計上の目的で集約に纏められる
- モデリングの際の一番の関心毎ではないものの、DB構造が制約である
3. サポートアーキテクチャ
8. ドメインモデルの紹介
データから振る舞いへの移行
- DDDはレコードの代わりにオブジェクトを使ってデータアクセスコードを記述するだけのアプローチではない
- ドメインモデルはビジネスのAPI
- クラスを基本的なビジネスコンセプトと一致させ、常に整合性を保つ事 => データより振る舞いに重点を置く
- DDDはドメインモデルの作成を優先し、モデリングされたドメインの永続化は後回しにする
- ドメインモデルは永続化に関与しない
ドメイン層の内側
- アプリケーション層はドメインとインフラ層を操作するためのオーケストレーションコード
- ドメインモデル: エンティティ/値オブジェクトから構成される
- モジュール: ドメインモデルを纏める名前空間
- リポジトリ: エンティティの永続化
- 契約(コンストラクト)はドメイン層、実装はインフラ層
集約
- モデル内のエンティティを纏めたり区切ったりする整合性の境界
ドメインモデルでは、複数のモデルを1つのコンテナに纏めたものを集約と呼ぶ
「集約とは、データを変更する目的で1つの単位として扱われる、関連するオブジェクトの集まりです」
- エンティティが参照できるのは、同じ集約内のエンティティか、別の集約のルートだけ
- 集約のルートの責務
- カプセル化されている全てのオブジェクトの永続化に対する責任
- クエリ操作で取得できるのは集約のルートだけ、内部オブジェクトへのアクセスは集約のルートのインターフェースを通じて発生しなければならない
// 集約ルートを示すmarker // 集約ルートだけがリポジトリを持つ、リポジトリの型制約として使う public interface IAggregateRoot { bool CanBeSaved { get; } } public class Order: IAggregateRoot { bool IAggregateRoot.CanBeSaved { get { return validate(); } } // ... }
ドメインサービス
- ドメインロジック(特定の集約に属さない、ほとんどの場合複数のエンティティにまたがっている)を実装するメソッドを持つクラス
- リポジトリ
- 永続化の為に存在する
- CustomerRepositoryのように集約ルート毎にリポジトリを1つ使用することになる
public interface IRepository<T> where T: IAggregateRoot { // interfaceを単なるmarker interfaceにしても良いし、一般的なメソッドを幾つか定義することも出来る T Find(object id); void Save(T item); }
public interface IDomainEvent {} public class CustomerReachedGoldMemberStatus: IDomainEvent { public Customer customer { get; set; } }
- 横断的関心事
9. ドメインモデルの実装
実用的なドメインモデルを作成するための護身術
- ドメインモデル貧血症
- エンティティが貧血と判断されるのは、エンティティに属しているものの¥、エンティティクラスの外側に配置されているロジックがある場合
- ex. メソッドがエンティティのメンバーのみを扱う場合は、そのエンティティに属している
DateTime EstimatedPayment(Invoice invoice)
- ex. メソッドがエンティティのメンバーのみを扱う場合は、そのエンティティに属している
- エンティティが貧血と判断されるのは、エンティティに属しているものの¥、エンティティクラスの外側に配置されているロジックがある場合
- エンティティのscaffolding
- 値オブジェクトのscaffolding
- 集約の特定
- 特別なケース
- モデルの永続化