Repositoryへ何を渡す?
メソッドによって異なる
Repositoryへ渡すものは、メソッドの目的によって異なります。取得には識別子や検索条件を渡し、保存には変更後のAggregate Rootを渡します。
findById()で取得する
取得したいAggregate Rootの識別子を渡します。
save()で保存する
変更後のAggregate Rootを渡します。
exists()で存在を確認する
確認したい対象の識別子や、業務上必要な条件を渡します。
delete()で削除する
設計に応じて、識別子またはAggregate Rootを渡します。
保存にはAggregate Rootを渡す
更新するときは、Repositoryへ変更項目を直接渡しません。取得したAggregate Rootのメソッドを呼び、業務ルールを確認して状態を変更してから、そのAggregate Rootをsave()へ渡します。
const recruitment = await repository.findById(recruitmentId);
if (!recruitment) {
throw new Error("募集が見つかりません");
}
// Aggregate Rootが業務ルールを確認して状態を変更する
recruitment.requestParticipation({
requesterId: participantId,
now: requestedAt,
});
// 変更後のAggregate Rootを保存する
await repository.save(recruitment);save(recruitmentId, participantId)のように変更内容だけを渡すと、Repositoryが業務上の判断まで担当することになります。Repositoryは保存を担当し、業務上の変更はAggregate Rootが担当します。
一部だけ変更する場合
開催場所だけを変更する場合でも、「募集」を表すAggregate Rootのメソッドを呼び、変更後のAggregate RootをRepositoryへ渡します。変更する項目の数ではなく、どのドメインモデルがその変更とルールに責任を持つかで判断するためです。
const recruitment = await repository.findById(recruitmentId);
// 「募集」が、開催場所を変更できる状態か確認して変更する
recruitment.changeLocation(newLocation);
// Repositoryには変更後の「募集」を渡す
await repository.save(recruitment);Aggregate Rootを渡しても、DBのすべてのカラムを更新する必要はありません。どのカラムを更新するかはRepositoryの実装やORMが判断できるため、開催場所のカラムだけを更新することもできます。
一つの項目を変更するたびに大きなAggregate全体を読み込む必要があるなら、Aggregateの範囲が広すぎないかを見直します。業務ルールを守るために本当に必要な範囲だけを、一つのAggregateにします。