DB からすべてのプロパティが入力された複数のオブジェクト、またはサブセットのみが入力された 1 つのオブジェクトを含むビジネス レイヤー
質問
私は中規模のシステムを構築しているのですが、おそらく皆さんの何人かが以前に直面したことがある問題に直面しています。私のビジネス層では、そのビジネス メソッドにとって重要なプロパティのサブセットを含むビジネス オブジェクトを返します。意味のない名前を持つオブジェクトが大量に発生したり、プロパティのサブセットのみが指定されたオブジェクトにのみ埋め込まれたりする可能性があるため、心配しています。方法。例を挙げてみましょう。
ケース1
たとえば、ユーザーは都市に属し、さらにその都市が州と国に属します。 User
, City
, State
そして Country
これはデータベース上のテーブルで、多くのフィールドがありますが、注文のリストを持つユーザーのリストが必要なので、次のようなビジネス オブジェクトを作成します。 UserWithOthers
重要なプロパティのみを含めます (UserId, UserName, CityName, StateName, CountryName, List<Order>
)、私の DAL はデータベースからそのフィールドのみを取得します。
ケース2
ここで注文金額をユーザーに返したいと考えています。最後にビジネス オブジェクトの次のフィールドを追加します (UserId, UserName, CityName, StateName, CountryName, OrdersCount
) そして、クラスはたとえば次のように呼び出すことができます UserWithOrderCount
いくつかの選択肢を考えてみました。
- その 2 つのビジネス クラスを作成し、それぞれの DAL メソッドに個別に入力します (このオブジェクトは単純ですが、そのメソッドには再利用のためにカプセル化する必要がある複雑な選択クエリがある可能性があることを考慮してください。そのため、リポジトリ パターンはここではうまく適合しません。少なくとも私はそう思います) )。
- オブジェクトを 1 つだけ作成する
User
すべてのプロパティ (UserId, UserName, CityName, StateName, CountryName, OrdersCount, List<Order>
) を使用し、各 DAL メソッドのサブセットのみを入力しますが、メソッドを使用する場合はセマンティック カップリングを意味します。フィールドのどのサブセットがデータベースから入力されるかを知る必要があり、セマンティック カップリングはすべてのカップリングの中で最悪であるためです。 - オプション 1 は、後で別のビューで両方が必要になった場合にうまく処理できません。
List<Order>
そしてOrdersCount
プロパティ。 - ここで、ASP.NET MVC を使用する場合、ビューに渡すために ViewModel が必要であると推奨することを考えてみましょう。Businnes Layer から ViewModel を返そうと考えましたが、それは良い考えとは思えません。何かに違反しています。また、ビジネス層が Web アプリケーションではなく別のアセンブリにあるため、不可能です。
- 同じ Linq クエリを何度も書きたくないのですが、NHibernate または EFCodeFirst を使用する場合はオプション 1 と同様で、大量のスモール ビジネス オブジェクトを作成する必要があります。
この状況にどう対処しますか?これは高度な設計上の決定だと思います。
解決
まず第一に、私はあなたに間違いなく同意します。
ビジネス オブジェクトを部分的に設定しないでください。どのプロパティが設定されているかを知る責任がビジネス層のクライアントに課されることになるため、これは非常に悪い習慣です。
ビジネス層から ViewModel を返さないでください。ビジネス層はアプリケーションのドメインのビジネス概念を表すことになっており、ViewModel はそのドメインの一部の特定のビューを表示するために必要なデータを含むデータ オブジェクトです。この 2 つはまったく異なるものであり、ビジネス層は次のことを行う必要があります。ビジネス オブジェクトがあらゆる種類の GUI で使用されていることをまったく意識しないでください。
私は最初の提案に従います。各ビジネス コンセプトを表す 1 つの個別のビジネス オブジェクトを作成します。次に、ORM (EF や NHibernate など) を使用してこれらのオブジェクトを設定し、オブジェクトのグループごとに専用のリポジトリを作成します。次に、リポジトリを呼び出すアプリケーション層を使用して、必要なオブジェクトを返します。この目的のために、これら 2 つのタイプを一緒に使用する必要があることがわかっている場合に備えて、結合されたユーザーとオーダーを返すメソッドをリポジトリに含めることができます。これにより、ユーザーと注文を表す個別の意味のあるエンティティを保持しながら、1 つのクエリでユーザーとそのすべての注文を返すことができます。