DDD において、強い不変条件で結ばれたエンティティ群を 1 つのトランザクション境界としてまとめた単位。外部からは 集約ルート(Aggregate Root) を経由してのみアクセスする。Eric Evans が『ドメイン駆動設計』で定義した。
なぜ集約が必要か
エンティティ間の参照を野放しにすると、整合性を守る責任が分散し、どこから不変条件が破られたのか追えなくなる。集約は 「ここまでは 1 トランザクションで一貫性を保つ/ここから先は結果整合性で良い」 という境界を明示する。
集約ルートとは
集約の代表として外部に公開される唯一のエンティティ。集約内の他オブジェクトは、必ずルート経由でしか参照・変更できない。
Order(集約ルート)
├─ OrderLine(集約内エンティティ)
├─ ShippingAddress(値オブジェクト)
└─ TotalAmount(値オブジェクト)
外部からは Order だけが見える。
OrderLine を直接取り出して変更してはいけない。
集約の設計原則
| 原則 | 説明 |
|---|---|
| 小さく保つ | 1 トランザクションで更新する範囲を最小化 |
| ルート経由でしか触らない | 集約内エンティティへの直接参照を禁止 |
| 集約間は ID で参照 | 別集約のオブジェクトを保持せず、ID だけ持つ |
| 不変条件はルートが守る | バリデーションを集約ルートに集約 |
| 1 トランザクション = 1 集約 | 複数集約の同時更新は結果整合性で繋ぐ |
よくある設計失敗
| 失敗 | 何が起きるか | 是正方針 |
|---|---|---|
| 集約が大きすぎる | 楽観ロックの競合多発・パフォーマンス低下 | 不変条件を見直して分割 |
| 集約をまたいで直接参照 | 整合性責務が分散・データ不整合 | ID 参照に置き換える |
| 集約ルートを通さず子を取得 | 不変条件をすり抜けた更新が発生 | リポジトリは集約ルートに対してのみ作る |
リポジトリとの関係
集約とリポジトリは 1 対 1。IOrderRepository は Order(集約ルート)を返し、OrderLine 単独のリポジトリは作らない。これが「リポジトリは集約ルートに対して 1 つ」の根拠。
集約をまたぐ業務はどう繋ぐか
複数集約を更新する業務は、 ドメインイベント+Saga や Process Manager で結果整合性として繋ぐのが定石。同一トランザクションで複数集約を一括更新すると、集約境界が崩れて DDD の利得が消える。
関連記事
- 開発手法ガイド:概要 — DDD 系列での位置づけ
- COBOL × DDD 設計パターン — レガシー業務から集約を抽出する例
関連用語
- DDD — 集約を含む戦術的設計の上位概念
- ビジネスケイパビリティ — 集約境界の上位にある業務能力単位
- リポジトリパターン — 集約ルートに対して 1 つ作る
- Saga パターン — 集約をまたぐ長期トランザクションの調停
- イベントソーシング — 集約に対する変化をイベントで記録する永続化
- SoC(関心の分離) — 集約境界が体現する分離原則