リポジトリーを設計するときに集約ルートを使用する必要がありますか?


8

多くのスレーブエンティティで構成されるマスターと呼ばれるエンティティがあります。

データベースに存在できるマスターは1つだけであり、リポジトリーを照会して、指定されたIDのスレーブを取得します。

最初にSlaveRepositoryを作成し、それをIDでクエリしました。それは問題なく機能し、他の開発者が私のリポジトリを使用できます。

次に、集約ルートについて考え、MasterRepositoryを作成してマスターを返し、それに対してループを実行して、必要なスレーブエンティティを取得しました。私がここで感じた問題は、これを他の開発者に公開すると、同じようにする必要があるため、GetSlaveByID(string id)と呼ばれるMasterRepositoryのメソッドを使用して、スレーブを直接取得できます(ループ機能を非表示にします) )。

さて、私のリポジトリはMasterRepositoryと呼ばれていてもスレーブを返す必要がありますか?そしてもっと重要なのは、どちらが正しい道なのか?

私はDDDとTDDを適用しようとする初期段階にあるので、どちらが正しい方法であるかを判断する前に、おそらく多くのことを検討する必要があります。

回答:


9

ドメイン駆動設計のエリック・エバンスの方法によると、非集合ルートのリポジトリーは避けるべきです。

彼は明確に述べています:

データベースクエリで直接取得できるのは、集合ルートのみです。それ以外はすべて、トラバーサルを介して行う必要があります。

しかし、これは、ルートのリポジトリがすべての要件を満たす必要があることも意味します。アグリゲートの一部に直接アクセスする必要がある場合は、アグリゲートのルートオブジェクトまたはそのリポジトリがそのための役割を果たします。

したがって、集約ルートリポジトリに次のようなメソッドを含めることはまったく問題ありません。

Slave GetSlave(string id)

ただし、DDDの子のIDは実際のルートオブジェクトのコンテキストでのみ意味があり、ルートなしでは浅いため、この署名は少し危険です。

これにより、リポジトリでの実装のためのより良い、よりDDDのようなアプローチにつながります。

Slave GetSlaveOfMaster(Master master, string slaveId)
// or
Slave GetSlaveOfMaster(Identity masterId, Identity slaveId)

しかし、私はおそらくこのメソッドをリポジトリに置くのではなく、マスターエンティティ自体にスレーブをすばやくアクセスさせることでしょう。ハッシュテーブルとして公開されている可能性もあります。それは私が考えることができる最もクリーンなアプローチです。

//within the Master entity
Slave GetSlave(Identity slaveId);

これで話は終わりではありません。マスターの知識がなくてもスレーブをフェッチする必要がある場合は、集約とオブジェクトモデルについて考える必要があります。おそらく、スレーブがルートである2番目のアグリゲートが必要で、それらのカスタムリポジトリが必要です。その場合、スレーブはマスターの子であるだけでなく、おそらくマスターへの参照も保持する別個の階層になります。マスターなしでスレーブオブジェクトが存在できるかどうかを知ることは重要です。可能であれば、別の集計がおそらく進むべき道です。


情報ありがとうございました。私はエリックの本を手に入れてもっと理解しようとするでしょう。
JD01

2番目の集計について言及しましたが、これは可能ですか?ルートアグリゲートとしてマスターがあり、同じモデルにスレーブがあると言っていますか?
JD01 2011

1
@ JD01:もちろんです。スレーブがルートである別のスレーブアグリゲートを持つことができます。ルートオブジェクトのみが公開されることを覚えておく限り、これはDDDに準拠しています。つまり、ルートではなく、複数の集合体の一部である3番目のクラスを持つことはできません。ただし、マスターアグリゲートから子としても参照されるスレーブアグリゲートを持つことができます。しかし、これはしばしば物事が複雑になる場所です(複雑な関係など)。ここでは、一部のルートが別のルートを参照する必要があるときにDTOオブジェクトを参照するだけで、これを簡略化しようとしています。DTOは読み取り専用であり、変更できません。
Falcon

1
@ JD01:これらのDTO参照はもちろん交換できますが、DTO自体は不変です。したがって、SlaveDtoをマスターから取得した場合、それを変更することはできません。変更したい場合は、独自のアグリゲートをフェッチして、そこで変更する必要があります。これらのDTOにはフラットデータのみが含まれ、階層は含まれず、必要なもののみが含まれます。
Falcon

1
@ JD01:また、マスターなしでスレーブが存在できるかどうかを自問する必要があります。できない場合は、集約ルートではありません。私の小さな更新を参照してください。
Falcon

1

一般に、集約境界内には1つのリポジトリのみが存在する必要があります。そして-Falconが言ったように-マスターとスレーブという2つの別々の集合体になるかもしれません。

ただし、質問の主な焦点はデータ検索であるように見えますが、DDDではそれが動作であるはずです。集合体の境界は、動作によって強制される制約(一緒に変化するものと適用される不変条件)の結果であり、集合体の内部構造はその選択の結果です。

たとえば、変更の必要性に応じて適切にグループ化した場合、外部リポジトリを呼び出す必要はそれほどありません。ほとんどの場合、Aggregateのビジネスオペレーションに必要なデータはすでに集計の境界内にあるはずです。異なる集計にアクセスする必要性は、おそらく一貫性のない境界のにおいです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.