2011-09-19 24 views
4

DDDの機能について質問したいと思います。 2つの集計があり、それぞれに値オブジェクトAddressが含まれているとします。したがって、Eric Evans DDDによれば、相互に集約を分離する必要があるため、最初の集約の集約ルートはAddressへのリンクを持つことができません。率直に言って、それは私にとっては意味がないようです。そのような状況を解決するにはどうしたらいいですか?どの集約にAddressを含めるべきですか?DDD集計と値オブジェクト

ありがとうございました

答えて

9

同じ値オブジェクトを使用している可能性があります。しかし、集約根が同じ境界コンテキストに存在し、したがって両方の集約で同じ意味を持つ場合にのみこれを実行します。集約が異なる有界コンテキストに存在する場合は、2つの独立したコンテキストを持ち、重複します。ある境界に入った文脈の懸念を別のものに漏らすことは、エリックが戦おうとしていることです。

ほとんどの場合、エンティティとバリューオブジェクトの懸念事項は、データの重複に問題がある人に沸き起こります。我々は、3つの通常の形式の単一の標準モデルで考えるように訓練されています。 DDDは、必要な場所で重複を強制し、一度と考えられていた概念を多くのものにすることによってもたらされる必然的な複雑さに対抗します。これはバリューオブジェクト

+0

境界のあるコンテキストと無制限のコンテキストの両方の例を挙げてください。より良い理解のために。 – madcyree

+1

注文が限定されたコンテキストと顧客の限定されたコンテキストがあり、アドレスが独立していたい場合は、顧客ARと受注ARは別々の状況にあります。 Order and Shipping info ARがある場合、それらは同じコンテキストにあり、同じAddress valueオブジェクトを使用できます。 –

+0

ありがとうございました:) – madcyree

8

を助け

希望は、いくつかの特性や 属性が記載されているが、アイデンティティの概念を運ばないオブジェクトです。

概念的なアイデンティティーを持っていないため、「参照」または「リンクする」ことはできません。あなたはそれを「含む」ことができます。ユーザーとユーザーに年齢があるとします。年齢は値オブジェクトです。ジョンが25歳で、ジェーンも25歳の場合、同じ年齢を「参照する」ことはありません。 Jonhの年齢はJaneの年齢と単純に等しい。したがって、住所が実際にバリューオブジェクトの場合は、集約境界に違反していません。あなたの集合ルートは等しいアドレスを持つだけです。たとえあなたが技術的にJava/C#のAddressへの参照を持っていても、Value Objectはほとんどの場合不変なので、問題はありません。

あなたが取り組んでいるドメインを知らなくても、あなたは質問に答えにくいです。しかし、一般的にAddressは必ずしもValue Objectである必要はありません。 Eric Evans氏は、bookにおいて、郵便サービスおよび配達ルートドメインがエンティティとして住所を扱うと述べています。技術者を送り出す電気会社は、 '123 Elm St'からの2つのサービスコールが実際に同じアドレスから来ており、1人の技術者を送る必要があることを認識する必要があります。この場合、住所または「住居」はエンティティです。

2

集計は、データ変更にのみ関連しています。同じデータを変更するには、2つの集約を許可するべきではありません。バリューオブジェクトは不変なので、このシナリオはこれからも起こりません。したがって、2つ以上の集約が同じ値オブジェクトを共有することは、読み取り専用データ構造であり、集約は読み取りモデルを気にしません。

Address a = new Address("1111 ABC Ave."); 
person.setAddress(a); 
letter.setAddress(a); 

person.getAddress().change("2222 XYS Ave.") // THIS IS ILLEGAL SINCE Address is a VO (immutable) 

上記のアドレスのために決して起こらないだろう、とあなたは人の住所にやる何が今までの手紙に影響を与えませんので、それは、共有することが危険ではないですので、手紙はまだそれが自身の不変条件だ保護されています。

住所がエンティティに作成されている場合、上記のコードは人物の変更に対して脆弱になり、境界を壊してしまうため、両方のエンティティで同じ住所を使用することはできません。それは手紙が不変量を支配するのを妨げるでしょう。

これはAggregate Rootsの全体のポイントであり、それは副作用を制限する方法でもあまりにもモデル的なものです。非常に明確な変更境界を定義すると、コードがより使いやすくなり、予期せぬ有害な影響を防ぐことができます。


もう1つ追加します。別の答えで言及されているように、別のBounded Contextに異なるAddressタイプを設定したいとします。その理由は、あるコンテキストでAddressの必要な詳細が、別のコンテキストで必要とするものと必ずしも同じではないということです。つまり、各コンテキストに2つのAddress型を持たせることで、一方のニーズを他方のニーズから分離します。あなたが必要な出荷のための

セイ:

Address 
{ 
    Number; 
    Unit; 
    Street; 
    State; 
    Country; 
    PostalCode; 
} 

しかし、あなたが必要とする場所のために:

Address 
{ 
    Number; 
    Unit; 
    Latitude; 
    Longitude; 
} 

DDDは、言う両方のアドレスそれらを呼び出すが、別のコンテキストにそれらをバインドします。したがって、言語ではすべて住所として話されていますが、具体的なデータや行動は、あなたが話している状況に応じて異なる場合があります。あなたが絶対にしてはいけないことは、ドメイン内のすべてのコンテキストのすべての可能なデータと動作を含む一種のMonsterAddresを作成し、これをすべてのコンテキストで使用されるAddress型にすることです。

あなたのアプリケーションのモデルについては、モンスターアドレステーブルにアドレスのすべてのデータを保存しても問題ありませんが、アプリケーションをモデリングするときは、ドメインにマッピングされた論理的な境界のあるコンテキストに分割する必要がありますそれが採用しているユビキタスな言語です。

関連する問題