Vernonによる「DDDの実装」:値オブジェクトかどうか?


8

この本の382ページに、(エンティティの)ルートの下で、値オブジェクトを集計で使用することについて説明している箇所があります。Product他の値に加えて、エンティティのSet<ProductBacklogItem>コレクションが含まれている例があります。

さて、バーノンはProductBacklogItemエンティティが値オブジェクトではなく、なぜであるかを説明しようとします:

ProductBacklogItemが値ではなくエンティティとしてモデル化されるのには、十分な理由があります。値オブジェクト(6)で説明したように、バッキングデータベースはHibernateを介して使用されるため、値のコレクションをデータベースエンティティとしてモデル化する必要があります。要素のいずれかを並べ替えると、かなりの数、またはすべてのProductBacklogItemインスタンスが削除されて置き換えられる可能性があります。これは、インフラストラクチャに大きなオーバーヘッドを引き起こす傾向があります。エンティティーとして、製品所有者が必要とする頻度で、すべてのコレクション要素にわたって順序付け属性を変更できます。ただし、MySQLでのHibernateの使用からKey-Valueストアに切り替える場合は、代わりにProductBacklogItemをValueタイプに簡単に変更できます。Key-Valueまたはドキュメントストアを使用する場合、

リポジトリの実装で、モデルがエンティティオブジェクトまたは値オブジェクトになるかどうかを判断する理由がわかりません。Key-Valueストアに行く場合でも、彼が話している順序が残っている可能性があります。

これは理にかなっていると思いますか?

回答:


1

その理由は、SQLデータベースはオブジェクトをリレーショナルな方法で格納するためです-アイテムは集約ルートとは異なるテーブルに格納され、それらはIDによって集約ルートを参照します。そのため、MySQLを使用するには、アイテムを(自動インクリメントで)プライマリIDを取得する別のテーブルに永続化されるエンティティとしてモデル化する必要があります。

Key-Valueストアなど。MongoDBでは、アイテムのコレクション全体を集約ルートの一部として保存できます。アイテムは(テーブル上で)個別のエンティティにならないため、値オブジェクトとしてモデル化できます。

例えば。ブログには、以下のコレクションとして保存されたコメントがあります。

{
  _id: 1,
  title: 'Some title',
  body: 'Blog body',
  comments: [{
     person: 'John Smith',
     comment: 'First comment of the blog',
     created_at: new Date()
  },
  {
     person: 'Peter Jackson',
     comment: 'Second comment of the blog',
     created_at: new Date()
  }],
}

1
これは完全に真実ではありません。「だからのMySQL使用する。それらは(自動インクリメントで)プライマリIDを取得する別のテーブルに永続化されたエンティティとしてモデルアイテムに必要それが許されるDDDで」値オブジェクトは主キーを持っているが、それは、モデル・インターフェースの一部(ありませんつまり、プライベートフィールドに格納されます)。そしてヴァーノン自身はこれを言って、例でこれを使います。したがって、私の混乱。
法律担当者、2014年

1

私はこの質問が数年前からであることを知っていますが、私は現在同様のモデリング問題に取り組んできました。おそらく、他の誰かがそこにある代替の意見を確認するのに役立つでしょう。

そのとおりです。このセクションは少し誤解を招くものであり、矛盾しています。DDDには多くの時間が費やされているため、ドメインの設計は永続性の懸念によって推進されるべきではないことを示しています。

推測すると、実際に参照されるのは値オブジェクトの不変の性質です。この例では、バックログアイテムの順序について具体的に説明します。値オブジェクトは不変であるため、1つのバックログアイテムの順序を変更すると、「削除されて置き換えられるProductBacklogItemインスタンスの数がすべてであっても、かなりの数になる」可能性があります。

したがって、技術的には依然としてインフラストラクチャによって駆動されますが、最終的にはSQLソリューションで順序を保持するために、値オブジェクトは変更可能でなければならず、したがって値オブジェクトではありません。この問題は、「集約インスタンスは通常、ストレージの1つの値表現としてシリアル化される」というNoSQLソリューションには存在しません。したがって、永続化によって設計を推進させるべきではありませんが、再順序付けを可能にするには、オブジェクトがエンティティにならないようにする方法はありません

ここで私自身のモデリングの問題が浮かび上がりました。アイテムの順序が重要である場合、私はそれらのオブジェクトがエンティティである必要があるという考えに取り組んできました...順序が重要である場合、識別も重要である必要があるためです。すなわち。各アイテムに特定のIDがない場合、どのようにアイテムを再注文しますか?順序が重要でない場合は、値のコレクション/バッグになり、値オブジェクトになる可能性があります。

私が検討してきたアプローチは、このインスタンスではOrderedBackLogItemであるエンティティによって順序を維持する必要があるということです。ただし、このエンティティにはProductBacklogItem値オブジェクトと順序付け属性が含まれています。

他の選択肢は、ヴァーノンが採用したアプローチ(1つのエンティティ)、またはコレクション自体が値オブジェクトであるため、順序付けされたリスト全体が毎回破棄され、再作成されます。

並べ替えが重要な場合に、リスト内の各アイテムがエンティティである必要があるかどうかについては、まだ2つの考えがあります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.