バックグラウンド
Udi Dahan は、データ アクセスに使用する便利なパターンとしてフェッチ戦略を提案しています。同意します。
概念は、役割を明確にすることです。たとえば、集約ルート - 顧客があります。アプリケーションのいくつかの部分に顧客が必要です。選択する顧客のリスト、顧客の詳細のビュー、および顧客を非アクティブ化するボタンが必要です。
Udi は、これらの役割ごとにインターフェイスを提案するようです。そのため、購入した最新の 10 個の製品を含むICustomerInList
非常に基本的な詳細と、顧客を非アクティブ化する方法があります。各インターフェイスは、それぞれの状況でジョブを完了するのに十分な数の Customer Aggregate Root を公開します。My Customer Aggregate Root は、これらすべてのインターフェースを実装しています。ICustomerDetail
IDeactivateCustomer
ここで、これらのロールごとにフェッチ戦略を実装したいと考えています。各戦略は、必要な情報のみを公開するインターフェースの背後にあるため、集計ルートに異なる量のデータをロードできます。
この部分を実装する一般的な方法は、Service Locator または他のスタイルの依存性注入を要求することです。このコードは、たとえば、必要なインターフェイスをICustomerInList
取得し、それをロードするためのフェッチ戦略を見つけます ( IStrategyForFetching<ICustomerInList>
)。この戦略は、ICustomerInList インターフェイスに必要な情報を含む Customer のみをロードすることを認識しているクラスによって実装されます。
ここまでは順調ですね。
質問
Service Locator またはIStrategyForFetching<ICustomerInList>
. 私が目にするすべての例は、既知の ID で 1 つのオブジェクトのみを選択しています。このケースは簡単です。呼び出し元のコードはこの ID を渡し、特定のインターフェイスを取得します。
検索したい場合は?それとも、顧客リストの 2 ページ目が必要ですか? ここで、Fetching Strategy が必要とするより多くの用語を渡したいと思います。
可能な解決策
私が見たいくつかの例では、述語 (特定の集約ルートが結果セットの一部である必要がある場合に true または false を返す式) を使用しています。これは条件には問題なく機能しますが、最初の n 人の顧客だけを取得する場合はどうでしょうか? または、検索結果の 2 ページ目を取得しますか? または、結果はどのようにソートされますか?
私の最初の反応は、汎用パラメーターを myIStrategyForFetching<ICustomerInList>
に追加し始めることIStrategyForFetching<TAggregateRoot, TStrategyForSelecting, TStrategyForOrdering>
です。これはすぐに複雑で見苦しくなります。リポジトリが異なると、さらに複雑になります。特定の選択方法を使用する場合にのみデータを提供するリポジトリもあれば、特定のタイプの順序付けのみを提供するリポジトリもあります。特定の方法でソートされた集約ルートのみを返す特殊なリポジトリとともに、ソート機能を使用できる一般的なリポジトリを柔軟に実装したいと考えています。
最初に使用したのと同じパターンを適用する必要があるように思えます - How do I make roles explicit? ペイロード Y (検索/順序付けパラメーター) を使用して X (集約ルート) を取得するための戦略を実装する必要がありますか?
編集 (2012-03-05)
毎回集約ルートを返さない場合でも、これはすべて有効です。各インターフェイスが異なる DTO によって実装されている場合でも、IStrategyForFetching を使用できます。これが、このパターンが強力である理由です。何を取得し、何を返すかを集約ルートにマップする必要はまったくありません。
使ってしまいましたIStrategyForFetching<TEntity, TSpecification>
。TEntity は私が取得したいものであり、TSpecification は取得したい方法です。