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