5

ASP.NET MVC プロジェクトで初めて DDD を実装しようとしていますが、いくつか苦労しています。

会社とサプライヤーの 2 つの関連エンティティがあります。私が最初に考えたのは、Company は集約ルートであり、Supplier は Company の値オブジェクトであるということでした。したがって、会社用のリポジトリがあり、サプライヤー用のリポジトリはありません。

しかし、アプリの構築を開始したため、サプライヤー用に別個のリスト、作成、および更新フォームが必要になりました。Company.Suppliers を呼び出すことができるリストは簡単で、Company.Suppliers.Add(supplier) を実行できる作成はひどいものでしたが、更新は頭痛の種です。必要なエンティティは 1 つだけであり、フォーム間で正確にメモリに貼り付けることができないため、会社とすべてのサプライヤーを再取得し、それにバインドする必要があるものを見つけて、再度変更して永続化する必要がありました。デシベルに戻ります。

Supplier のリポジトリがあれば、本当に GetOne を実行する必要がありました。GetOneSupplier を Company または CompanyRepository に追加することで回避策を追加できますが、それは厄介なようです。

したがって、それが実際には値オブジェクトであり、完全なドメイン エンティティ自体ではないのではないかと考えています。

tldr;

別のリスト/作成/更新ビュー/ページが必要なのは、エンティティが独自のルートであるべきであることを示していますか?

4

2 に答える 2

37

あなたの用語に基づいて、Eric Evans の本に基づいて DDD を実行していると思います。モデリングの最初の段階ですでに問題を特定しているように思えますが、それは正しいことです。

あなたはサプライヤーをValue Object...と考えていたと言いましたが、そうではないことをお勧めします。AValue Objectは、主にそのプロパティによって識別されるものです。たとえば、日付「2009 年 9 月 30 日」は値オブジェクトです。なんで?月/日/年の組み合わせが異なるすべての日付インスタンスは異なる日付であるためです。同じ月/日/年の組み合わせを持つすべての日付インスタンスは同一と見なされます。私の「2009 年 9 月 30 日」をあなたの「2009 年 9 月 30 日」と交換することについて議論することはありません。

Entity一方、 は主にその「ID」によって識別されます。たとえば、銀行口座には ID があり、すべてに口座番号があります。銀行に 2 つの口座があり、それぞれに $500 がある場合、それらの口座番号が異なっていれば、同じです。それらの特性 (この例ではバランス) は、それらを識別したり、同等であることを意味したりしません。残高が同じだったとしても、銀行口座を交換することについて議論するに違いありません:-)

したがって、あなたの例では、Entity各サプライヤーは主にそのプロパティではなく ID によって識別されると推測するため、サプライヤーを と見なします。私自身の会社は、世界の他の 2 つの会社と同じ名前を持っています。

オブジェクトをCRUDするためのビューが必要な場合は、Entity経験則としておそらく正しいと思いますが、あるオブジェクトを他のオブジェクトと区別するもの、つまりプロパティまたはIDにもっと焦点を当てる必要があります。

ここまでAggregate Rootは、オブジェクトのライフサイクルとアクセス制御に焦点を当てたいと思います。それぞれに多くのコメントが含まれる多くの投稿があるブログを持っているとしAggregate Rootます。(s) はどこにありますか? コメントから始めましょう。投稿せずにコメントするのは理にかなっていますか? コメントを作成してから、投稿を見つけて添付しますか? 投稿を削除した場合、そのコメントを残しておきますか? Aggregate Root投稿は、 1 つの「葉」 (コメント) を持つものであることをお勧めします。ここで、ブログ自体について考えてみましょう。ブログと投稿との関係は、投稿とコメントの関係に似ています。私の意見では、それもAggregate Root「葉」が1つある投稿です。

あなたの例では、会社とサプライヤーの間に強い関係があり、会社を削除すると (私は知っています...おそらく会社のインスタンスは1つしかありません)、そのサプライヤーも削除しますか? 「スターバックス」(米国のコーヒー会社) を削除すると、そのコーヒー豆のサプライヤーはすべて存在しなくなりますか? これはすべてドメインとアプリケーションに依存しますEntitiesAggregate Roots、おそらくどちらも . 言い換えれば、企業はサプライヤーへのアクセスやライフサイクルを管理していません。サプライヤーとは 1 対多 (または多対多) の関係にあるだけです。

これにより、 が得られRepositoriesます。ARepositoryは、格納および取得用Aggregate Rootsです。2つあります(技術的には何も集約していませんが、「リポジトリは集約ルートまたは集約のリーフではないエンティティを格納する」と言うよりも簡単です)、したがって、 two が必要ですRepositories。1 つは会社用、もう 1 つはサプライヤー用です。

これが役立つことを願っています。おそらく、エリック・エヴァンスがここに潜んでいて、私が彼のパラダイムから逸脱した場所を教えてくれるでしょう.

于 2009-10-01T03:21:01.890 に答える
1

私には簡単なことのように思えます-サプライヤーは独自のリポジトリを持つ必要があります。エンティティがモデル内に独立して存在する可能性があるという論理的な可能性がある場合は、ルート エンティティにする必要があります。そうしないと、とにかく後でリファクタリングすることになり、冗長な作業になります。

追加の実装作業が前もって行われるにもかかわらず、ルート エンティティは常に値オブジェクトよりも柔軟です。モデル内の値オブジェクトは、モデルが進化するにつれて時間の経過とともに希少になることがわかりました。通常、値オブジェクトのままであるエンティティは、最初からそのように論理的に制約できるものでした。

企業がサプライヤを共有している場合、サプライヤをルート エンティティとして持つと、データの冗長性も削除されます。これは、企業ごとにサプライヤ定義を複製するのではなく、代わりに参照を共有するためです。また、企業とサプライヤ間の関連付けも双方向にすることができます。より多くの利益をもたらします。

于 2009-10-01T03:11:52.123 に答える