2008-09-16 8 views
10

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

答えて

15

CRUD-ishメソッドはリポジトリの一部でなければなりません。しかし、私はなぜあなたはCRUDメソッドの束を持っているのか尋ねるべきだと思います。彼らは何を本当にですか?彼らは何ですか本当に?実際にアプリケーションで使用するデータアクセスパターンを呼び出すと、リポジトリはずっと便利になり、特定のタイプの変更がドメインに発生したときにショットガンの手術を受ける必要がなくなります。

CustomerRepo.GetThoseWhoHaventPaidTheirBill() 

// or 

GetCustomer(new HaventPaidBillSpecification()) 

// is better than 

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

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

集計ルートがある場合は、リポジトリの爆発を防ぎ、ロジックが広がることはありません。データアクセスパターンは4 x xありません。データアクセスパターンは4つあります。ルーツ。

これは私の$ 0.02です。

2

DDDでも、データアクセスクラスとルーチンをエンティティとは別にしています。

理由は、あなたがエンティティを追加として

  1. テスト容易性は、長期的には
  2. より保守懸念の
  3. 分離とモジュラー設計を改善し、ある

は、私は専門家でないルーチン、ちょうど私の意見。

1

NilssonのDDD & Pを適用したときの厄介なことは、「私は実際のアプリケーションではそうしないだろうが...」と彼の例が続きます。トピックに戻る:私はOrderRepository.GetOrdersByCustomer(customer)が行く方法だと思っていますが、DDDについてのALT.Netメーリングリスト(http://tech.groups.yahoo.com/group/altdotnet/)のディスカッションもあります。

3

あなたが話していることは両方の方法で行っています。ここでは、自分のドメインクラスがドメインクラスであることだけを心配している永遠の無知な(またはPONO - Plain Ole '.Net Object)メソッドです。彼らは、彼らがどのように永続しているか、あるいは永続していても何も知らない。もちろん、これについて実用的でなければならず、IDなどのものを許可する必要があります(ただし、IDを持つレイヤースーパータイプを使用するので、デフォルト値のようなものが1つのポイントになることがあります)

これの主な理由は、私は単元責任の原則に従うよう努めていることです。この原則に従うことで、私は自分のコードがよりテスト可能で保守可能であることがわかりました。私は考えることが1つしかないので、必要なときに変更を加える方がずっと簡単です。

注意すべきことの1つは、リポジトリに苦しむ可能性のある方法の膨らみです。 GetOrderbyCustomer .. GetAllOrders .. GetOrders30DaysOld .. etcなど。この問題の1つの良い解決策は、Query Objectパターンを見ることです。そして、あなたのリポジトリは実行するためにクエリオブジェクトを取り込むことができます。

また、NHibernateのようなものを調べることを強くおすすめしたいと思います。

5

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

Active Recordモデルの1つの欠点は、(ほとんどの言語で)特に侵入的なコードを除いて、単一の永続性モデルをかなり前提としていることです。

リポジトリインターフェースは、ドメイン層で定義されていますが、あなたのデータはデータベースに保存されているかどうか分かりません。リポジトリのパターンでは、InMemoryRepositoryを作成して、ドメインロジックを単独でテストし、アプリケーションで依存関係注入を使用してサービスレイヤにSqlRepositoryをインスタンス化させることができます。ちょうどテストのための特別なリポジトリを持つ多くの人々に

は、間抜けに聞こえるが、リポジトリのモデルを使用している場合、あなたは本当にあなたの特定のアプリケーションのためのデータベースを必要としないことがあります。単純なFileRepositoryがそのトリックを行うことがあります。あなたがそれを必要としていることを知る前に、データベースに自分自身を結婚させることは潜在的に制限していますデータベースが必要な場合でも、InMemoryRepositoryに対してテストを実行する方がずっと高速です。

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

4

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

customer.Orders; 

質問に答えるために、CRUD操作は集約ルートリポジトリにあります。

CustomerRepository.Add(customer); 
CustomerRepository.Get(customerID); 
CustomerRepository.Save(customer); 
CustomerRepository.Delete(customer);