2017-03-06 29 views
1

集約ルートのメンバエンティティがルートエンティティを指し示すことはできますか?ルートエンティティを指すDDD /集約ルート/メンバーエンティティ

Population AR(Populationはルートエンティティで、PopulationMembershipはメンバーエンティティの1つです)があるとします。

私はPopulationとPopulationMembershipの関連付けの方向性を評価しています。もう一方のエンティティ、Person(独自のAR、PopulationMembershipにはPersonへの参照があります)があります。

ER(データベース)世界では、通常、PopulationMembershipからPopulation(PopulationとPersonの間の多対多関係の接続テーブルであるpopulation_membership)を指す関連付けを行います。

しかし、私はDDDの世界では、その習慣を崩し、Population(概念モデルでは)からPopulationMembershipに向かうように関連付けを行うべきだと思います。

とにかく、私はメンバーエンティティからルートエンティティへの関連付けが許可されているかどうかを確認したいと思います。

どのような考えですか?

+1

これは多分私の質問に関連しています:http://stackoverflow.com/questions/9804815/associations-traversal-direction このハイライトで:「エンティティAとエンティティBの間に関連がある場合は、多くの場合、自分自身がABだけを使用していることが分かります.Aは集計ルートであり、常にあなたの出発点です。 少なくとも、エンティティがルートエンティティに直接関連付けられている場合、その方向は常にルートエンティティから来ることが示唆されます。右? –

+0

[Associations 'traversal direction]の可能な複製(http://stackoverflow.com/questions/9804815/associations-traversal-direction) – guillaume31

答えて

1

[OK]を、のは、二つの部分にこの質問を分割してみましょう:メンバーエンティティがその集約ルートへの参照を保持するため

  1. は、それは大丈夫ですか?
  2. 一般集約モデリングルール

のは、1から始めましょう:

いいえ、一般的に子エンティティが集計根への参照を保持するべきではありません。集約ルートは、集約全体へのエントリポイントであり、一貫性の境界を維持する必要があります。つまり、集合へのすべての変更は、ルートエンティティ(ルートエンティティのメソッドを呼び出すことによってoop内で)に転送する必要があります。集約ルートは子エンティティへの参照を返すことができますが、一時的でなければなりません。また、クライアントは集約ルート外の子エンティティへの変更を実行すべきではありません。そうしないと、一貫性が侵害される可能性があります。そのことを念頭に置いて、子エンティティが自分のルートへの参照を保持する理由は実際には分かりません(クライアントの観点からは、すでにルートにアクセスしていますか?)。私が今見ている唯一の例外は、モデルをいくつかの特定のニーズに変換する必要がある場合です(プレゼンテーション層には意味のあるJSON出力を生成するためにルートエンティティIDが必要です)。しかし、このような場合でも、別個の読み取りモデルを作成したり、必要なDTOを構築するための特殊なアセンブラを用意することになります。

[OK]を、今、第二の点に:

あなたのドメインエンティティあなたのデータベースモデルを構築するのと同じ方法をモデル化しようとしているようです。 DDDでは、まず、ビジネス要件とモデルの動作に焦点を当てる必要があります。意味のあるドメインモデルを構築する場合、データの関係はそれほど重要ではありません(少し後で改良します)。まず、ドメイン専門家からビジネスケースシナリオを収集することに焦点を当てる必要があります。集約は、実際のビジネス不変量に基づいて構築する必要があります。チーム(ビジネスメンバーを含む)とともに共通のモデルを作成する必要があります。いくつかのナレッジ・クランチ・セッションの後、デザインが完全に異なって見える可能性は非常に高いです。おそらく、Personは実際には集約ルートではなく、単なる値オブジェクトですか? PopulationMembershipエンティティは必要ないでしょうか?集約の最も一般的な設計は、複数の値オブジェクトを持つ単なる(ルート)エンティティです。それ以外にも、私はしばしば、ドメインモデルへの接続(idを除く)なしで、完全に別個のデータベースモデルを作成します。私はドメイン< - > dbmodelの間で変換する翻訳レイヤー(マッパーコンポーネント)を使用します。私の最近のプロジェクトでは、私のdbモデルはドメイン層とは非常に異なっていました(例えば、永続層のニーズに合わせて調整されました。リレーショナルDBの場合は、双方向の関係を明示的に指定することもできます(実際にはormを使用する必要はありません)。 dbモデルとドメインモデルを分離することには多くの利点があります。デザインははるかにしなやかです。しかし、db < - >ドメイン層間のマッピングコスト(開発者作業)は、単純なプロジェクトでは大きすぎることがあります。そのような場合、私は通常、共通のモデルから始め、次にリファクタリングして分離可能なレイヤーにします。

もう1つ重要なことです。他の集約ルーツをIDだけで参照することは、一般的には良い考えです。このように、複雑なオブジェクトグラフには問題はなく、単一のトランザクション内で他の集約を変更することを心配する必要はありません(集約ルートは他のルートを変更すべきではありません)。集約間で通信する必要がある場合は、代わりにイベントを使用します。

は、ヴォーンバーノンによって記事の偉大なシリーズをご参照ください:

http://dddcommunity.org/library/vernon_2011/

私はこれらの記事は、あなたが集計モデリングの概念を理解するのに役立つことができると思います。

+0

データベースモデルからドメインモデルを分割するために追加したいと思います。 CQRSを使用することができます。ここでは、書き込みモデル(別名集計)と読み取りモデル(UI /プレゼンテーションの表示内容)の2つのモデルがあります。 CQRSを選択すると、この分離は非常に自然で明確です。 –

+0

@ ConstantinGALBENUご意見ありがとうございます。はい、書き込みと読み取りのために別々のモデルを作成することをお勧めします。これらのモデルでは、異なるレイヤーの特定のニーズに合わせて、異なるデータベースを使用することもできます。しかし、私の答えでは、データベースから直接マッピングされたデータのみの(論理なし)クラスを記述するために "データベースモデル"という用語を使用しました。私たちが使用する技術に応じて、私たちのドメインクラスはdbマッピングクラスとほとんど同じであるか、まったく異なっていてもかまいません(例えば、ドメインクラスはdbマッピングクラスの複雑なオブジェクトとフラットなプリミティブを使用します)。 –

関連する問題