10

EvanとNilssonの本を読んだ後でも、ドメイン駆動プロジェクトでデータアクセスを管理する方法がわかりません。CRUDメソッドがリポジトリの一部である必要があります(つまり、OrderRepository.GetOrdersByCustomer(customer))か、エンティティの一部である必要があります:Customer.GetOrders()。後者のアプローチはよりOOのように見えますが、単一のエンティティタイプのデータアクセスを複数のオブジェクト、つまりCustomer.GetOrders()、Invoice.GetOrders()、ShipmentBatch.GetOrders()などに分散します。挿入と更新はどうですか?

4

6 に答える 6

15

CRUD っぽいメソッドは、リポジトリの一部にする必要があります... っぽい。しかし、CRUD メソッドがたくさんある理由を尋ねるべきだと思います。彼らは本当に何をしますか?彼らは本当に何のためにいるのですか?アプリケーションが使用するデータアクセスパターンを実際に呼び出すと、リポジトリがより便利になり、ドメインに特定の種類の変更が発生したときにショットガン手術を行う必要がなくなると思います.

CustomerRepo.GetThoseWhoHaventPaidTheirBill()

// or

GetCustomer(new HaventPaidBillSpecification())

// is better than

foreach (var customer in GetCustomer()) {
    /* logic leaking all over the floor */
}

「保存」タイプのメソッドもリポジトリの一部である必要があります。

集約ルートがある場合、これにより、リポジトリの爆発が発生したり、ロジックが全体に広がったりするのを防ぐことができます: エンティティのデータ アクセス パターンの数は 4 倍ではなく、集約ルートで実際に使用するものだけです。

それは私の 0.02 ドルです。

于 2008-09-16T21:23:36.567 に答える
5

DDDは通常、Customer.Saveでヒントを与えるアクティブレコードパターンよりもリポジトリパターンを優先します。

Active Recordモデルの欠点の1つは、(ほとんどの言語で)特に煩わしいコードを除いて、単一の永続性モデルをほぼ想定していることです。

リポジトリインターフェースはドメインレイヤーで定義されていますが、データがデータベースに保存されているかどうかはわかりません。リポジトリパターンを使用すると、InMemoryRepositoryを作成して、ドメインロジックを分離してテストしたり、アプリケーションで依存性注入を使用して、サービスレイヤーにSqlRepositoryをインスタンス化させたりできます。

多くの人にとって、テスト専用の特別なリポジトリを用意するのはおかしなことに聞こえますが、リポジトリモデルを使用する場合は、特定のアプリケーション用のデータベースは実際には必要ないことに気付くかもしれません。単純なFileRepositoryでうまくいく場合もあります。必要だと気付く前にデータベースに自分自身と結婚することは、潜在的に制限的です。データベースが必要な場合でも、InMemoryRepositoryに対してテストを実行する方がはるかに高速です。

ドメインロジックがあまりない場合は、おそらくDDDは必要ありません。ActiveRecordは、多くの問題に非常に適しています。特に、ほとんどのデータとほんの少しのロジックがある場合はなおさらです。

于 2008-09-16T22:16:40.557 に答える
4

少し後退しましょう。Evansは、リポジトリがエンティティだけでなく集約ルートを返すことを推奨しています。したがって、顧客が注文を含む集約ルートであると仮定すると、リポジトリから顧客をフェッチすると、注文も一緒に来ました。顧客から注文への関係をナビゲートすることにより、注文にアクセスします。

customer.Orders;

したがって、あなたの質問に答えるために、CRUD操作は集約ルートリポジトリに存在します。

CustomerRepository.Add(customer);
CustomerRepository.Get(customerID);
CustomerRepository.Save(customer);
CustomerRepository.Delete(customer);
于 2008-09-20T16:20:24.800 に答える
3

私はあなたが話している両方の方法でそれを行いました、私の好ましいアプローチは今あなたのドメインクラスがドメインクラスであることだけを心配している永続的な無知(またはPONO-プレーンオレの.Netオブジェクト)メソッドです。彼らは、彼らがどのように永続化されているか、あるいは彼らが永続化されているとしても、何も知りません。もちろん、これについては実用的で、Idなどを考慮に入れる必要があります(ただし、それでも、Idを持つレイヤースーパータイプを使用するだけなので、デフォルト値などが存在する単一のポイントを持つことができます)

これの主な理由は、私が単一責任の原則に従うよう努めていることです。この原則に従うことで、コードのテストと保守がはるかに容易になりました。また、考えるべきことが1つしかないため、必要なときに変更を加えるのもはるかに簡単です。

注意すべきことの1つは、リポジトリが苦しむ可能性のあるメソッドの肥大化です。GetOrderbyCustomer .. GetAllOrders .. GetOrders30DaysOld ..など。この問題の1つの良い解決策は、クエリオブジェクトパターンを調べることです。そして、リポジトリはクエリオブジェクトを取り込んで実行することができます。

NHibernateのようなものを調べることも強くお勧めします。これには、リポジトリを非常に便利にする多くの概念が含まれています(IDマップ、キャッシュ、クエリオブジェクトなど)。

于 2008-09-16T21:41:23.403 に答える
2

DDD であっても、データ アクセス クラスとルーチンをエンティティから分離しておきます。

理由は、

  1. テスト容易性が向上
  2. 関心の分離とモジュール設計
  3. エンティティ、ルーチンを追加すると、長期的にはより保守しやすくなります

私は専門家ではありません、私の意見です。

于 2008-09-16T21:18:51.367 に答える
1

Nilsson の DDD&P の適用に関する厄介な点は、彼が常に「現実世界のアプリケーションではそれをしないだろうが...」で始まり、その後に彼の例が続くことです。トピックに戻る: OrderRepository.GetOrdersByCustomer(customer) がよい方法だと思いますが、ALT.Net メーリング リスト ( http://tech.groups.yahoo.com/group/altdotnet/ )での議論もあります。 DDDについて。

于 2008-09-16T21:28:56.320 に答える