Aggregate(集約)
Aggregate(集約)とは
Aggregateは、業務上の操作で一緒に確認するドメインモデルを、一つの単位として扱う範囲です。この範囲の中で業務ルールを守ります。
具体例で整理する
例えば、「募集」では、参加希望者から「参加申請」を受け付けます。フットサルNOWでは、主催者による承認は行わず、条件を満たした参加申請は自動で参加確定になります。
参加申請を受け付けるときは、「期限を過ぎていたら受け付けない」「同じ人の申請は二重に受け付けない」「定員に達していたら受け付けない」というルールがあります。
これらのルールを守るには、「募集状態」「申込期限」「定員」「参加者」を一緒に確認する必要があります。そのため、これらを一つの「募集」として扱います。このドメインモデルの範囲がAggregateです。
募集を表すドメインモデル
募集
Entity・Aggregate Root
ルールの確認に使うもの
- 募集状態
- 定員
- 参加者ID
- 申込期限
参加申請の受付で守るルール
「募集」が、必要な情報を使って次のルールを確認します。
期限を過ぎていたら受け付けない
確認する情報:申込期限
同じ人の申請は二重に受け付けない
確認する情報:参加者ID
定員に達していたら受け付けない
確認する情報:定員と現在の参加者数
集約の範囲を決める
集約の範囲は、画面やデータベースの構造ではなく、一つの業務上の操作で一緒に守るルールを基準に決めます。
ディレクトリで表す
フットサルNOWでは、「募集」のAggregateに含めるドメインモデルをdomain/recruitment/に置きます。
src/features/futsal/
└── domain/
└── recruitment/ ← 「募集」のAggregateを置くディレクトリ
├── RecruitmentEntity.ts ← Aggregate Root
├── RecruitmentStatusValueObject.ts
├── RecruitmentCapacityValueObject.ts
├── ParticipantIdValueObject.ts
└── ParticipationRequestDeadlineValueObject.ts集約の範囲はディレクトリ名ではなく、どの業務ルールを一緒に守るかによって決まります。このディレクトリは、決めた範囲をコード上でも分かりやすくするための配置例です。
※ DDDで必須の命名ではありません。このガイドラインでは、ファイル名やクラス名だけで役割を見分けやすくするため、EntityとValueObjectを名前に付けています。Aggregate RootはEntityに与えられる役割なので、名前には付けず注釈で示します。