5

私はさまざまな場所で、DDD の重要な要件の 1 つは、リポジトリの制限されたコントラクトを持つことであると読みました。

findByName(string name)
findByEmail(string email)
etc.

また、一般的なクエリ インターフェイスを提供しない:

findBySpecification(Specification spec)

これが重要である理由は理解できます。テスト用にリポジトリをモックしたり、基礎となる永続化フレームワークを変更したりできるためです。

このルールをアプリケーション全体に適用するのはそれほど難しくありませんが、ユーザーに「高度な検索」フォームを提供する場合に適用する方法がわかりません。

ブログ投稿をキーワード日付、作成などで検索できるフォームがあるとします。

これらの基準は自由に組み合わせることができるため、ユースケースごとに方法を提供することはできません。

findByKeyword(string keyword)
findByDateRange(Date from, Date to)
findByKeywordAndDateRange(string keyword, Date from, Date to)
findByDateRangeAndAuthor(Date from, Date to, User author)
etc.

何かが足りないのでしょうか、それとも規則の例外の 1 つですか?

4

3 に答える 3

2

仕様をパラメータとしてリポジトリに渡すことに問題はありません。これは、実際には、リポジトリ インターフェイスでのメソッドの爆発に対処するための非常に優れた方法です。この回答を見てください。「高度な検索」シナリオでは、「仕様」よりも「フィルタ」の方が適切な名前かもしれません。このコードは DDD ガイドラインに違反していないと思います。

Filter filter = new FilterBuilder()
    .WithinDateRange(dateRange)
    .IncludingKeywords("politics", "news")
    .ByAuthor("John Smith")
    .Build();

blogs.FindByFilter(filter);

フィルターを作成するコードは、ドメイン外に置くことができることに注意してください。ドメインルールに違反しないためです。「匿名の投稿者が投稿したブログはモデレーターの承認が必要」のようなルールがある場合はどうなりますか? Filter で表現することもできますが、そうするとビジネス ロジックの一部が外部化されます。このルールをドメイン コードに入れ、次のような専用のリポジトリ メソッドを用意する方が理にかなっています。

blogs.RequireModeratorAttention();
于 2011-09-05T02:27:31.933 に答える
1

リポジトリ パターンには、次の 2 つの主な利点があります。

  1. アプリケーションを永続化レイヤーとイディオムから切り離します。
  2. 明確に定義され、理解されているドメイン セグメントへのデータ アクセスを一元化し、制限します (リポジトリ内のデータ アクセス方法は、明確に定義された結果を持ち、合理的にテスト可能です)。

永続化レイヤー (NHibernate Criteria など) によって提供される仕様パターンのインスタンスを使用する場合、利点 1 を無効にします。仕様パターンをまったく使用すると (自分でロールするものであっても)、2 番目の利点が台無しになります。

そうは言っても、検索インターフェースなどの状況では、仕様が必要です - 確認して独自のものを作成してください.

于 2011-09-05T03:08:19.367 に答える
1

このルールをアプリケーション全体に適用するのはそれほど難しくありませんが、ユーザーに「高度な検索」フォームを提供する場合に適用する方法がわかりません。

実際、必要なものが検索フォームだけであれば、これらすべての抽象化のコストを支払う必要はありません。リポジトリ (少なくとも DDD のコンテキストでは) は、永続化フレームワークのニュアンスをビジネス ロジック (アプリケーション層) から抽象化するように設計されました。

ユーザーのアドレスを変更するコマンドがある場合は、アプリ レイヤーに魔法の Hibernate コードを配置するよりも、FindUserById メソッドを使用してリポジトリを配置する方が適切です。これには2つの理由があります

  • 永続層 (リポジトリ) をモックしてアプリケーション層をテストすることをお勧めします。
  • アプリケーション レイヤーはビジネス ロジックであるため、気にする必要があります。

UI 用のデータを取得するためだけに、これらすべてが必要なわけではありません。UIレイヤーに存在する可能性のある特殊な「Finder」クラスを使用することをお勧めします。それらは、抽象的な「仕様」または (さらに良い) 裸の Hibernate (またはお気に入りの ORM) のいずれかで動作できます。このアプローチに関するブログ投稿をここに書きました。

于 2011-09-05T05:40:17.923 に答える