2

与えられた:

  • レイヤー プレゼンテーション、ビジネス、およびデータを備えたアーキテクチャがあります。
  • ドメイン駆動設計を適用しています。
  • オブジェクト指向のクエリを作成できるオブジェクト リレーショナル マッパーを使用しています (例: HQL クエリを作成できる NHibernate)。

質問:

オブジェクト指向クエリをどのレイヤーに配置する必要がありますか?

私の考え:

それらをプレゼンテーション層に入れることは通常意味がないと思います。しかし、それらをビジネスレイヤーまたはデータレイヤーのどちらに配置するかはわかりません。

例 (NHibernate):

ビジネス ロジックにメソッド GetCustomersPossiblyInterestedIn(Product p) が必要だとします。次に、顧客が p と同じカテゴリの製品を購入済みの顧客オブジェクトを選択する複雑な HQL クエリを作成できます。

引数 a)

一方で、このクエリは明らかにビジネス ロジックであると言えます。なぜなら、顧客が同じカテゴリの製品を購入したかどうかに基づいて、ある製品に興味を持っている可能性があると見なされるという決定はビジネス上の決定だからです。同様の価格で同じカテゴリの複数の製品を購入した顧客を選択することもできます。

引数 b)

一方、ビジネス レイヤーはデータ レイヤーに依存すべきではないため、ビジネス レイヤーで NHibernate を直接使用すると警鐘が鳴ります。

考えられる解決策 1)

ビジネス層で使用する独自のオブジェクト指向クエリ言語を作成し、データ層で HQL に変換します。これにより、多くのオーバーヘッドが発生すると思います。解析されたクエリ言語の代わりにクエリ オブジェクトに基づくクエリ言語を使用する場合は、多少の労力を費やす可能性がありますが、私の反論は依然として当てはまります。

考えられる解決策 2)

NHibernate が HQL や ISession などで提供できる抽象化レベルはビジネス層に適合するため、ビジネス層で NHibernate を直接使用しても問題ありません。包む必要はありません。

どう思いますか?

編集:

密接に関連する議論については、Ayende Rahien による「Repository is the new Singleton」および「The false myth of encapsulated data access in the DAL」を参照ください。

4

3 に答える 3

1

間違いなく、オブジェクト指向のクエリをプレゼンテーション レイヤーに配置することは避けてください。ビジネス ロジック層 (BLL) から受信したデータのみを表示/使用する必要があります。クエリなしで。BLL から受け取った結果を照会する必要がある場合は、BLL を拡張して、照会する必要のないデータを提供する必要があります。

「オブジェクト指向クエリ言語」を使用するというあなたのアイデアは、うまくいっています。通常、この「言語」はあなたのDALです:)「オブジェクト指向クエリ言語」の良い例は、適切に実装されたデータアクセス層(DAL)です。

私の見解では、DALはすべての機能の 80 ~ 90% を実装し、次のような一連の機能を提供する必要があります。

  • 顧客 GetCustomerById(int customerId);
  • リスト GetLastRegisteredCustomers(int カウント);
  • 等...

これらの関数は、照会する必要のない必要な機能の大部分を提供します。

めったに使用されない他のすべての 10 ~ 20% のクエリ (「オブジェクト指向」と名付けました) については、DAL は IQueryable の結果を返すメソッドを実装する必要があります。少なくとも 'GetAll()' メソッドと、おそらくいくつかのカスタマイズ:

  • IQueryable GetAll();
  • IQueryable GetCustomerByCountry(int countryId);

この場合、今年 BLL に登録された国で顧客を見つける必要がある場合は、次のように電話します。

List<Customer> customers = GetCustomerRepository()
    .GetCustomerByCountry(countryId)
    .Where(customer=>customer.RegisterDate.Year==year)
    .ToList<Customer>()
    ;

IQueryable<> インターフェイスを提供するものを知っていると思います。

NHibernate で Linq を使用する方法: Linq to NHibernate

追加のヒント: DAL 実装には「リポジトリ」パターンを使用することをお勧めします。しばらく前に、私はこれを一般的なアイデアとして使用しました: http://habrahabr.ru/blogs/net/52173/ (ロシア語を読むことができない場合は、Google でページ全体を翻訳してください - 読めるはずです)。

それが役立つことを願っています。

于 2010-09-23T14:30:49.847 に答える
0

私は、何らかのリポジトリを使用して NHibernate (または他の ORM) をラップすることを好みます。たとえば。NHibernate の場合、リポジトリは NHibernate セッションをラップします。このリポジトリはクラスごと (つまり、CustomerRepository と OrderRepository) にすることも、ドメインにあまり多くのクラスがない場合は、単一のリポジトリから開始することもできます。

これは、Criteria クエリ (LoadAllByName、LoadCustomerWithOrder など) を配置するのに最適な場所です。後で別の ORM または別の永続化メカニズムに切り替える必要がある場合 (非常にまれだと思います)、リポジトリを含むデータ層全体を交換できます。

于 2010-09-23T14:20:44.520 に答える
0

クエリはリポジトリに属します。GetCustomersPossivelyInterestedIn(Product p) の関数シグネチャは必要な場所にある場合がありますが、クエリ自体はリポジトリ クラスにのみ存在する必要があります。

于 2010-09-23T14:23:26.760 に答える