web-dev-qa-db-ja.com

DDD-集約ルートのリポジトリは集約の保存を処理しますか?

既存のアプリケーションのグリーンフィールドモジュールにDDDのようなアプローチを使用しています。アーキテクチャにより100%DDDではありませんが、いくつかのDDDコンセプトを使用しようとしています。 ConversationMessageの2つのエンティティで構成される制限付きのコンテキストがあります(これは適切な用語です-私はまだDDDについて学習しています)。メッセージは会話なしには存在せず、システム内のすべてのメッセージは会話の一部であるため、会話がルートです。

データベースで会話を検索するConversationRepositoryクラスがあります(実際はゲートウェイに似ていますが、「リポジトリ」という用語を使用しています)。会話が見つかると、(ファクトリーを介して)その会話のメッセージのリストも作成します(プロパティとして公開されます)。本格的なMessageRepositoryクラスはConversationが取得されたときにのみ存在するため、必要なものではないため、これは正しい処理方法のようです。

ただし、メッセージの保存に関しては、メッセージの集約ルートであるため、これはConversationRepositoryの責任ですか?つまり、AddMessageと呼ばれるConversationRepositoryに、メッセージをパラメーターとして受け取り、データベースに保存するメソッドが必要ですか?または、メッセージを検索/保存するための別のリポジトリを用意する必要がありますか?論理的にはエンティティごとに1つのリポジトリのようですが、「コンテキストごとに1つのリポジトリ」と聞いたこともあります。

28
Wayne Molina

ブルーブック は、DDDアプローチを最大限に活用したい場合は、一読の価値があります。 DDDパターンは自明ではなく、それぞれの本質を知ることは、どのパターンをいつ使用するか、アプリケーションをレイヤーに分割する方法、集約を定義する方法などを考えるのに役立ちます。

あなたが言及している2つのエンティティのグループは、境界コンテキストではありません-おそらく集約です。各Aggregateには、他のすべてのオブジェクトのAggregateへの単一のエントリポイントとして機能するエンティティであるAggregate Rootがあります。したがって、エンティティと、集約ルートではない別の集約内の別のエンティティとの間の直接の関係はありません。

リポジトリは、他のオブジェクトの走査では簡単に取得できないエンティティを取得するために必要です。通常、リポジトリには集約ルートが含まれていますが、通常のエンティティのリポジトリも存在する場合があります。

あなたの例では、会話は集約ルートのようです。おそらく、会話がアプリケーションの開始点であるか、または他のオブジェクトの単純なトラバースを通じて満足のいく形でアクセスできないように、詳細な基準でそれらを照会したい場合があります。このような場合は、クエリを実行したり、直接追加したり、直接削除したりする一連のメモリ内会話のような錯覚をクライアントコードに与えるリポジトリを作成できます。一方、メッセージは会話のトラバーサルによって簡単に取得できます。詳細な基準に従ってそれらを取得する必要はなく、会話のすべてのメッセージを一度に取得するだけなので、リポジトリは必要ありません。

ConversationRepositoryはメッセージの永続化に役割を果たしますが、あなたが述べたような直接的な役割は果たしません。そのため、ConversationRepositoryにはAddMessage()はありません(そのメソッドはConversation自体に属しています)代わりに、リポジトリがConversationを永続化するたびに、ORMフレームワークを使用する場合は透過的にメッセージを永続化することをお勧めします(N)Hibernateなど、必要に応じてアドホックSQLを使用するなど.

25
guillaume31

ConversationServiceを作成し、コンストラクタにIConversationRepositoryIMessageRepositoryを挿入できます。単純なCRUD操作にはリポジトリを使用し、その他すべてのサービス(キャッシュ、ロジックの保存など)を使用します

3
šljaker