29

DDD とリポジトリ パターンについて質問があります。

Customer 集約ルート用の Customer リポジトリがあるとします。Get & Find メソッドは、Address などのオブジェクトを含む完全に設定された集計を返します。すべて問題ありません。しかし、ユーザーが UI で顧客を検索するときは、集約の「要約」、つまり要約された情報を含むフラットなオブジェクトだけが必要です。

これに対処する 1 つの方法は、通常どおりリポジトリで find メソッドを呼び出し、アプリケーション レイヤーで各顧客集計を CustomerSearchResult / CustomerInfo DTO にマップし、それらをクライアントに送り返すことです。

しかし、これに関する私の問題はパフォーマンスです。各 Customer 集計では、すべての関連付けを設定するために複数のクエリが必要になる場合があります。したがって、私の検索基準が 50 人の顧客と一致した場合、DB では、必要のないデータを取得する可能性があるため、かなりのヒットになります。

もう 1 つの問題は、最後の注文日など、Customer の集計ルート境界の外側にある顧客に関する要約データを含めたい場合があることです。注文には独自の集計があるため、顧客の注文情報を取得するには、OrderRepository を呼び出す必要があり、パフォーマンスも低下します。

だから今、私は2つのオプションが残っていると思います:

  1. 1 つの効率的なクエリを実行して、これらの集計オブジェクトのリストを返す追加の Find メソッドを CustomerRepository に追加します。

  2. 1 で説明した find メソッドだけを持つ、専用の読み取り専用の CustomerInfoRepository を作成します。

しかし、どちらも DDD の原則に反しているように感じます。私のリポジトリは、T : IAggregateRoot という一般的なベースから継承します。これらの要約情報オブジェクトは集計ではなく、T とは異なる型であるため、実際には #1 は設計に反します。

おそらく #2 では、IAggregateRoot 制約なしで抽象的な SearchRepository を作成しますか?

私のドメインには多くの同様のシナリオがあります。

このシナリオをどのように実装しますか?

ありがとう、デイブ

アップデート

Theo の回答を読んだ後、オプション #2 を使用して、これらのシナリオ向けのインフラストラクチャ内に特殊な SearchRepository を作成すると思います。アプリケーション層 (WCF サービス) は、ドメイン エンティティを DTO にマッピングするのではなく、要約 DTO を直接設定するだけのこれらのリポジトリを呼び出すことができます。

**** アップデート 2 ****

1年以上前にこれを尋ねましたが、この正確な問題を解決することを目的としたCQRSを発見したことを付け加えたいと思いました。Udi Dahan ( http://www.udidahan.com/ ) と Greg Young ( http://codebetter.com/gregyoung/ ) は、それについて多くのことを書いています。DDD を使用して分散アプリケーションを作成する場合は、CQRS が最適です。

4

2 に答える 2

30

要約した情報だけを表示したいと思います。これらの要約された情報は、ドメイン モデルのエンティティまたは値オブジェクトではありません。それらは単なる情報であり、それ以上のものではありません。

報告情報を表示するようなものです。私がそのようなことに対処する場合、純粋な DDD アプローチに固執することはありません。提案されたオプションは問題ありません。これで仕事が完了します。DDD をドグマとして扱うべきではありません。既成概念にとらわれずに考えてください。少しDDDを緩めます。

ただし、表示目的でモデルの外部に情報値を作成しているだけであることに注意してください。そのため、ユーザーが (ドメイン モデルで定義されている) 何らかの操作を行うために 1 ビットの情報を選択した場合、情報値から識別子を抽出し、エンティティ/値オブジェクト/集計をリポジトリから引き出す必要があります。

このビデオを強くお勧めします: Eric Evans: What I've Learned About DDD since the book . 彼の本を読むなら、ビデオ全体を見るべきです。Eric Evans 自身が集計について話し、現在抱えている問題に言及している 30:00 頃に非常に注意してください。

于 2010-01-20T00:25:05.157 に答える
1

私は...するだろう:

  1. 表示するオブジェクトのビューを表す別のオブジェクト (CustomerInfo など) を返します。
  2. DataTable を返します。多くの場合、汎用コンテナーが最も簡単で最適な方法です。

汎用ベース リポジトリの T が Customer の場合、集約ルートの概念を誤って適用していると思いますが、私は厳密なEvansangelistではありません。DataTables や Customer データのビューである読み取り専用オブジェクトなど、Customer と論理的または快適にグループ化されるデータを返す Customer 用のリポジトリを設計します。

于 2010-01-20T00:23:56.657 に答える