ドメイン主導の設計で、主キーを持つデータベーステーブルを値オブジェクトに変換するにはどうすればよいですか?


8

次のように定義されたデータベーススキーマがあるとします。

Person.mail_address_key ----- Address.address_key
Person.billing_address_key ----- Address.address_key

A Personには郵送先住所と請求先住所があります。非正規化手法として、別のAddressテーブルを作成します。時間のほとんどは、mail_address_keyおよびbilling_address_key単一のはPerson同じ値になります(例:自分の郵送や請求先住所のキーが同じになります)。

私のデータベースAddressは、IDがあります(アドレスキー)。しかし、私のドメインモデルではAddress、がエンティティになる説得力のある理由はわかりません。値オブジェクトにしたいのですが。

  1. DDDでは、これはオプションですか?または、値オブジェクトは通常、(テーブルではなく)列のグループですか?データベースがドメインモデルの構造を指示するべきではないと思うので、ここでは悪魔の擁護者を演じています。
  2. もしそうなら、アドレスはどこで/いつ/どのようにデータベースのアイデンティティを失うので、ドメインレイヤーの値オブジェクトとして使用できますか?または、データベース識別子を値オブジェクトに保持することになっていますか?
  3. モデルをデータベースに永続化する必要がある場合、プロセスは何ですか?私はa)これらのフィールドでアドレスを検索し、b)存在しない場合は新しいアドレスを作成しますc)存在する場合はフィールドを更新しますか?

電子メールアドレスを使用可能な値オブジェクトにすることは非常に難しい場合があります。電子メールアドレスが等しいかどうかをテストすることは簡単ではなく、おそらく郵便アドレスをテストすることもそうではないためです。
SpaceTrucker 2014年

@SpaceTruckerモデルを値オブジェクトにするかどうかの決定に考慮すべきだと言っていることは何も読んだことがないと思います。
Daniel Kaplan 2014年

回答:


2

DDDでは、これはオプションですか?または、値オブジェクトは通常、(テーブルではなく)列のグループですか?データベースがドメインモデルの構造を指示するべきではないと思うので、ここでは悪魔の擁護者を演じています。

データベースはドメインモデル構造を指示するべきではないので、あなたはそれについて正しいです。値オブジェクトは、値オブジェクトが運ぶデータのタイプに応じて、列またはテーブルとしてデータベースに格納できます。

もしそうなら、アドレスはどこで/いつ/どのようにデータベースのアイデンティティを失うので、ドメインレイヤーの値オブジェクトとして使用できますか?または、データベース識別子を値オブジェクトに保持することになっていますか?

ドメインコードは、永続性を完全に無視する必要があるため、永続性などのその他の懸念事項であるプロパティで処理されないようにする必要があります。本当に集約ルートに焦点を当てるべきです。集計ルートをデータベースに保存するときに何らかの方法で特定する必要があるため、その時点で、Personテーブルレコード(Personが集計ルートであると想定しています)を確認して、存在するかどうかを確認するだけで済みます。 MailingAddressIDまたはBillingAddressIDフィールドの値。その時点で、新しいアドレスを作成し、リンクを変更して新しいアドレスを指すようにするか、すでにリンクされているアドレスを上書きするかを決定できます。

モデルをデータベースに永続化する必要がある場合、プロセスは何ですか?私はa)これらのフィールドでアドレスを検索し、b)存在しない場合は新しいアドレスを作成しますc)存在する場合はフィールドを更新しますか?

上記の回答で少し説明したように、集計ルートに基づいてオブジェクトグラフをハイドレートおよびデハイドレートする必要があります。したがって、リポジトリがデータベースから集約ルートを取得すると、データベース内の集約ルートに関連付けられている、集約ルートの下にある必要なエンティティと値オブジェクトもすべてハイドレートされます。集約ルートをデータベースに保存する場合も同様です。リポジトリは、集約ルートの下でオブジェクトグラフ全体を処理できる必要があります。


ああ、それは非常に理にかなっています。助けてくれてありがとう。
Daniel Kaplan 2014年

2

DDDはDBスキーマをまったく強制しません。値オブジェクトは、列のグループ、dbエンティティ(3番目のソリューション)として実装できます。たとえば、ドキュメント指向のデータベースを使用できる場合は、単に非正規化された形式で実装できます。状況に応じて、最適なオプションは何ですか。

DBはドメインの状態を維持するためのツールにすぎないことに注意してください。設計上の決定を強制するべきではありません。何らかの理由でDBでの値オブジェクトの表現にIDを使用する必要がある場合は、そのようにしますが、この実装の詳細をドメイン自体に漏らさないでください。ラッパーを作成する/ドメインクラスを拡張する/フレームワークが許可するものは何でも、IDを完全に分離したインフラストラクチャクラスに追加して、アプリケーション/フレームワークが状態を永続化できるようにします。


いくつかの具体的な実装を表示できますか(疑似コードの場合もあります)?
Daniel Kaplan

-1

この場合、DDDの特別な要件はありません。郵送先住所と請求先住所を人のプロパティとしてモデル化し、別のテーブルに保存できます。次に例を示します。

Person
+ MailingAddress : Address
+ BillingAddress : Address

または

Person
+ MailingAddressID
+ MailingAddress : Address
+ BillingAddressID
+ BillingAddress : Address

1
私はこれが私の質問のすべて(または過半数)に答えているとは思わない
Daniel Kaplan
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.