2013-07-31 10 views
8

私はDDDで初めての試みをしています。私は集合設計に問題があります。DDD - 小さな集約ルートを持つ不変条件を適用する

私のアプリケーションには3つのエンティティが含まれています。グラフ、ノード、リンク。これらのエンティティのそれぞれは、ユーザーが変更できるnameプロパティを持っています(これは、 'name'をEntity IDとして不適切と考えています)。グラフにはノードの集合が含まれ、ノードには発信リンクの集合があります(この問題の目的のために、着信リンクを無視することは安全です)。各ノードは一度に1つのグラフにのみ関連付けることができます(ただし、グラフ間で移動することができます)。同様に、各リンクは、任意の時点で(ただし移動することができます)、1つのノードに関連付けることができます。

私が強制しようとしている不変な点は、すべてのエンティティ名が親コレクション内で一意であることです。上で説明したアーキテクチャでは、不変式が実際のコレクションにあるので、コレクションの所有者(グラフとノード)が両方とも集計ルートでなければならないと決めました。

私の問題は、ノード上で名前を不変にする方法です。リンク上では、ノードAR内に隠れているので簡単であり、ノードはすべてのリンクの名前変更/移動がこの不変条件を破らないことを確認することができる。しかし、私が見る限りでは、不変量を破る可能性のあるNodeの直接的な名前変更を防ぐことは何もありません。最終的な一貫性はここでは許容できるオプションではありませんが、これは真のシステム不変量でなければなりません。

私が考えているアプローチは、Node.Rename()が実際に不変式を強制することですが、私の懸念は、名前変更が有効かどうかを確認するために親グラフを調べることです。これは正しく感じられません - グラフはこの名前空間制約を強制するものでなければならず、Nodeはそれについて何も知りません。

私はこれが意味をなされることを望み、人々の考えを聞くのを楽しみにしています。

編集:上記のドメインモデルは、ドメイン全体の単純化されたサブセットです。すべてのエンティティが単一のAR内に保持されるには複雑すぎる.......

+2

"グラフはこの名前空間制約を強制するものでなければならず、Nodeはそれについて何も知りません。 - ビンゴ! – MattDavey

+1

@MattDavey - あなたはARだけをGraphにするべきですか?どのようにして、すべてのノードの名前変更が親のグラフを経由しなければならないかを私が強制することはできません。このような場合には、[Vaughan essay](http://dddcommunity.org/wp-content/uploads/files/pdf_articles)の最初の試行と同様に、私は1つの巨大な「神」ARで終わることを心配しています。 /Vernon_2011_1.pdf) – tonyj444

+1

もしそれが本当のシステム不変式ならば、 'Graph'を一つのARとして維持するのが道に思えます。唯一のARとして 'Graph'を使用すれば、どれくらい大きくなるのでしょうか、並行性はどれくらいですか? – JefClaes

答えて

6

解決策は、CQRSのアプローチをとったものです。優れたCQRS紹介hereが見つかりました。

私の「書き込み」モデルでは、グラフ、ノードおよびリンクはすべて集約ルートですが、名前はすべて親コレクションによって管理されます。したがって、書き込みモデルでは、ノードは自分の名前が何であるか分かりません(名前の更新は所有するグラフを経由しなければならないという意味です)。対応する「読み取り」モデルでは、名前はノードに直接関連付けられます(これは表示に便利です)。

このソリューションの利点は、ARを小さく保つことができるということですが、「名前」情報が親コレクション内に保持されているため、クロス集約不変量を維持することに問題はありません。

+0

問題を解決できたと聞いて良かったです。私はCQRSについても読んだことがありますが、実際にはそれを実践することはありません。しかし、おそらく私は、私のプロジェクトの部分を実装しやすくするでしょう:) –

+0

'graph.renameNode(node、name)'または 'node.renameChild(childNode、name)'メソッドを持っていますか?ノード名を取得して設定することで、正確な実装は何ですか?名前はどこに保存しますか?それらはノード属性であるか、コレクションに含まれていますか?名前 - >ノードマップ? – inf3rno

18

あなたのコメントですでに締結しているように、唯一の集計ルートはGraphでなければなりません。

凝集体と凝集体根の違いはです。あなたの例では、グラフとノードの両方が集約ですが、集約全体を管理するオブジェクトはグラフです。これは根です。

オブジェクトが集約ルートの場合アイデアを得るための最も簡単な方法は、自分自身を依頼することです:

それは親から切り離されただけでこのオブジェクトを、持っている意味を成していますか?

回答が「いいえ」の場合は、おそらく集約ルートではありません。たとえば、単一のノードは親グラフの一部でない場合はおそらくほとんど役に立たないでしょう。だからこそ、あなたは通常、集約根のためのリポジトリしか持っていません。対応する集約ルートの一部ではないオブジェクトへのアクセスを防ぐためです。不変条件の上で今

。あなたは基本的に右があなたの質問に答え、[グラフ]

親内一意である

すべての[ノード]名前:あなたは(強調鉱山)と述べました。単一のノードのコンテキストでは、その名前が一意であると言うのは意味がありません。しかし、グラフの文脈では、のグラフの不変量であり、ノードではないためです。したがって、グラフはprotecting this invariantを担当します。

「god aggregate root」に関しては、グローバルビジネスの観点からは単一の集約ルートを持つことは珍しいことではありません。しかし、DDDの重要な側面は、システム内のさまざまなコンテキストを特定することです。システムには、多くのGraphオブジェクトを含む上位レベルのルートが存在する場合があります。グラフを管理するこの高水準のコンテキストでは、おそらくグラフ内の低レベルのリンクオブジェクトには関心がありません。

コンテキストオブジェクトに従ってドメインオブジェクトをモデル化することが重要です。これは私がここ数ヶ月間に実現した最も重要なことの一つです。ほとんどの人は、リポジトリやエンティティや価値オブジェクトのためにDDDについて知っていますが、これらは境界のあるコンテキストほど重要ではありません。

何かの唯一のビジネスコンセプトがあっても、何か、コンテキストごとに単一の実装のこの概念を表す複数のモデルを持っている完全に罰金です。あるインプリメンテーションは集約ルートであり、他のインプリメンテーションはより大きな集約の一部であり、すべてがコンテキストに依存します。

一般的なソフトウェアマントラは、コードの再利用、DRYなどについてです。最初は、同じビジネスコンセプトを表す複数のクラスを持つのは間違っていました。しかし、いったんこの気持ちを解消して、それぞれの実装に独自の責任があることを理解すれば、それは非常に簡単になりました。

+1

「ほとんどの人はリポジトリやエンティティやバリューオブジェクトのためにDDDについて知っていますが、これらは境界があるコンテキストほど重要ではありません。 - +1します。 – MattDavey

+3

うわー、これは私の心を吹き飛ばしています。 BCは基本的にシステム全体の一部を構成するさまざまなアプリケーションに使用されていたという印象を受けました。このようなことを考えると、残りのドメインモデルに大きな影響があります。これは私に多くのことを考えさせる(そして学ぶ)ことができました。それだけが良いことになることができます。 – tonyj444

+0

BCを掘り起こして読んでいたので、私はこのアプローチを使って実際のプロトタイプを作りました。私が遭遇した問題は、2つのBCの間に多くのコミュニケーションが必要であったことを意味し、彼らは非常に緊密に結合され、彼らはもはや真のBCではないと思われ始めました。何かの単一の概念を表す複数のモデルについてのあなたの説明は、私にとって大きな前進でした。そして、私をCQRSに導いてくれました。 – tonyj444

関連する問題