IRepositoryからIQueryableを返す


8

リポジトリパターンを使用して、一般的な使用のために、データセット(テーブル)のIQueryableを返すことは適切ですか?

これは多くの場合に非常に便利です。特に、そのインターフェイスを利用する外部ライブラリ、たとえば、UI要素をソート/フィルタリングしてバインドするプラグインを使用する場合に便利です。

ただし、IQueryableを公開すると、デザインにエラーが発生しやすくなる場合があります。これと遅延読み込みの誤った使用を組み合わせると、パフォーマンスが大幅に低下する可能性があります。

一方、使用方法ごとにアクセスメソッドを用意することは冗長であり、多くの作業(ユニットテストなど)も必要です。


2
IMO:持続性テクノロジ(EF、NHibernate)を開発者から隠すことは悪い考えです。このテクノロジーが公開するものを公開するだけです。
陶酔

@Euphoric Ok、ただしASP.NET MVCの場合、new DbContext()必要なときにいつでも喜んで作成し、いつでも呼び出すことができる3000行のコントローラーがありますSaveChanges()。何もテストすることは不可能であり、私が考えることができる唯一のことは、それを隠す追加のレイヤーです。
Mateusz

@Mateuszそれはテクノロジーの問題ではなく、人の問題です。だらしない開発者か、そうでない開発者を適切に訓練することができないだらしない管理者がいます。
陶酔する

回答:


12

Mark Seemannがこのテーマについて優れたブログ投稿を公開しています:IQueryable is Tight Coupling。彼は最後の部分(私の強調)でそれをうまくまとめています:

これはすべて理論的な演習だと思うかもしれませんが、実際には重要です。Clean Codeを作成するときは、APIの機能が明確になるようにAPIを設計することが重要です。

このようなインターフェースは誤った保証をします:

public interface IRepository
{
    IQueryable<T> Query<T>();
}

LSPとPostelの法則によれば、返されたインスタンスに対して(どんなに複雑であっても)クエリ式を記述できることが保証されているように見え、常に機能します。

実際には、これは決して起こりません。

そのようなインターフェースを定義するプログラマーは常に特定のORMを念頭に置いており、その特定のORMに対して安全であることがわかっている境界内に留まる傾向があります。これは漏れやすい抽象化です。

特定のORMを念頭に置いている場合は、それについて明確に説明してください。インターフェースの背後に隠さないでください。ある実装を別の実装に置き換えることができるという錯覚を引き起こします。実際には、それは不可能です。イベントストアを介して実装を提供しようとしていると想像してください。

ケーキは嘘です。

Entity FrameworkのようなORMのは、あるリポジトリと作業パターンの単位の実装。それらを別のものにラップする必要はありません。


返信いただきありがとうございます。私の懸念はSeemannの問題に何度も遭遇しているようですが、私は実際に彼を読むために時間をかけていません。私が同意しない唯一のことは、リポジトリは(たとえ強く結合されていても)より単純なアクセスレベル(VisibleItems、DeletedItemsなど)であってもビジネスロジックをカプセル化し、DRYの概念を支援するのに非常に役立つことです。
Mihalis Bagos 2012

@Kristof「エンティティフレームワークはリポジトリと作業ユニットパターンの実装です」への質問です。人々がnew DbContext()MVCの単一のメソッドでコントローラーと複雑なロジックを配置せず、ビューにいくつかのロジックも配置しないようにするために私ができることは何ですか?単体テストを実行できないレガシーコードがあります。テストを有効にし、人々が本当に悪いコードを実行しないようにするには、追加のレイヤーが必要です。したがって、教育目的で自分のリポジトリを実装する必要があります。
Mateusz

サービスクラスまたはコマンドとクエリクラスのような他のオプションがあります。
Kristof Claes、2015年

1

これについてはコンセンサスはありません。私の意見と経験では、リポジトリは特定の用途を持つオブジェクトを返す必要があります。少なくとも、DDDでEric Evensによって定義されたリポジトリパターンを使用する場合。リポジトリは、ビジネスロジック、永続性、およびファクトリを接続する「ブリッジ」です。

より永続的にアクセスしたい場合は、ゲートウェイパターンを探している可能性があります。

ただし、ここで言うことから、その持続性への露出を非表示にして、プロキシパターンが便利になるようにします。


持続性への暴露は主要な問題ではありませんが、親子エンティティなどのパターンの少なくとも最上位の抽象化は必須です。それらの模様も調べていただき、ありがとうございます!
ミハリスバゴス2012
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.