114

DDDを読み始めたばかりです。エンティティと値のオブジェクトの概念を完全に理解することはできません.値オブジェクトがエンティティオブジェクトとして設計されている場合にシステムが直面する可能性のある問題 (保守性、パフォーマンスなど) を誰かが説明できますか? 例は素晴らしいでしょう...

4

10 に答える 10

124

本質的な区別に縮小すると、アイデンティティはエンティティにとって重要ですが、値オブジェクトにとっては重要ではありません。たとえば、誰かの名前は値オブジェクトです。Customer エンティティは、顧客の Name (値オブジェクト)、List<Order> OrderHistory (エンティティのリスト)、およびおそらく既定の Address (通常は値オブジェクト) で構成されます。顧客エンティティには ID があり、各注文には ID がありますが、名前には ID があってはなりません。一般に、とにかくオブジェクト モデル内では、Address の ID はおそらく重要ではありません。

通常、値オブジェクトは不変オブジェクトとして表すことができます。値オブジェクトの 1 つのプロパティを変更すると、基本的に古いオブジェクトが破棄され、新しいオブジェクトが作成されます。これは、コンテンツほど ID に関心がないためです。正しくは、オブジェクトのプロパティが別のインスタンスのプロパティと同一である限り、Name の Equals インスタンス メソッドは "true" を返します。

ただし、Customer などのエンティティの一部の属性を変更しても、顧客は破棄されません。通常、Customer エンティティは変更可能です。ID は同じままです (少なくともオブジェクトが永続化されると)。

おそらく、気付かないうちに値オブジェクトを作成しています。きめの細かいクラスを作成することによってエンティティのいくつかの側面を表すときはいつでも、値オブジェクトを取得しています。たとえば、有効な値にいくつかの制約がありますが、より単純なデータ型で構成されるクラス IPAddress は、値オブジェクトになります。EmailAddress は文字列にすることも、独自の動作セットを持つ値オブジェクトにすることもできます。

データベースで ID を持つアイテムでも、オブジェクト モデルで ID を持たない可能性は十分にあります。しかし、最も単純なケースは、一緒に意味のあるいくつかの属性を組み合わせたものです。Customer.FirstName、Customer.LastName、Customer.MiddleInitial、および Customer.Title を Customer.Name として一緒に構成できる場合は、おそらくそれらを使用したくないでしょう。永続性について考える頃には、おそらくデータベース内の複数のフィールドになっているでしょうが、オブジェクト モデルは気にしません。

于 2008-09-16T19:03:01.023 に答える
44

すべての属性によって集合的に定義されるオブジェクトは、値オブジェクトです。いずれかの属性が変更された場合、値オブジェクトの新しいインスタンスが作成されます。これが、値オブジェクトが不変であると定義されている理由です。

オブジェクトがすべての属性によって完全に定義されていない場合、オブジェクトの ID を構成する属性のサブセットがあります。残りの属性は、オブジェクトを再定義せずに変更できます。この種のオブジェクトは不変で定義できません。

区別するためのより簡単な方法は、値オブジェクトを決して変更されない静的データと考え、エンティティをアプリケーションで進化するデータと考えることです。

于 2008-10-21T12:19:43.290 に答える
7

以下が正しいかどうかはわかりませんが、Addressオブジェクトの場合、エンティティへの変更はすべてのリンクされたオブジェクトに反映されるため、EntityではなくValueオブジェクトとして使用したいと思います(たとえば、人)。

この場合を考えてみましょう。あなたは他の人と一緒に家に住んでいます。アドレスにエンティティを使用する場合、すべてのPersonオブジェクトがリンクする一意のアドレスが1つあると主張します。一人が引っ越した場合、あなたは彼の住所を更新したいと思います。住所エンティティのプロパティを更新すると、すべての人が異なる住所を持ちます。値オブジェクトの場合、アドレスを編集することはできず(不変であるため)、その人に新しいアドレスを提供する必要があります。

これは正しいですか?DDDの本を読んだ後、私もこの違いについてまだ混乱していたと言わなければなりません。

さらに一歩進んで、これはデータベースでどのようにモデル化されますか?AddressオブジェクトのすべてのプロパティをPersonテーブルの列として使用しますか、それとも一意の識別子を持つ別のAddressテーブルを作成しますか?後者の場合、同じ家に住む人々はそれぞれAddressオブジェクトの異なるインスタンスを持ちますが、それらのオブジェクトはIDプロパティを除いて同じです。

于 2008-09-18T10:07:13.650 に答える
5

アドレスは、忙しいプロセスに依存するエンティティまたは値オブジェクトにすることができます。アドレス オブジェクトは宅配便サービス アプリケーションではエンティティにできますが、他のアプリケーションではアドレス オブジェクトに値オブジェクトを指定できます。クーリエ アプリケーションでは、アドレス オブジェクトの ID が重要です

于 2010-03-18T12:59:05.320 に答える
2

私は別のスレッドでこれについて尋ねましたが、私はまだ混乱していると思います。パフォーマンスの考慮事項とデータモデリングを混同している可能性があります。カタログ化アプリケーションでは、顧客は必要になるまで変更されません。それはばかげているように聞こえますが、顧客データの「読み取り」は「書き込み」をはるかに上回り、多くのWebリクエストはすべてオブジェクトの「アクティブセット」にヒットしているため、顧客を何度​​もロードし続けたくありません。それで、私はCustomerオブジェクトの不変の道を進んでいました-それをロードし、キャッシュし、そして顧客を見たい(マルチスレッドの)リクエストの99%に同じものを提供します。次に、顧客が何かを変更したときに、「エディター」を取得して新しい顧客を作成し、古い顧客を無効にします。

私の懸念は、多くのスレッドが同じ顧客オブジェクトを認識し、それが変更可能である場合、1つのスレッドが変更を開始すると、他のスレッドで騒乱が発生することです。

私の現在の問題は、1)これは合理的であり、2)プロパティに関する多くのコードを複製せずにこれを行うための最善の方法です。

于 2009-04-21T13:41:56.207 に答える
0

値オブジェクトとエンティティの違いをよりよく理解するために、ウィキペディアの次の例を検討してください。

価値オブジェクト:人々がドル紙幣を交換するとき、通常、それぞれの固有の紙幣を区別しません。彼らはドル札の額面だけを気にしています。このコンテキストでは、ドル札は価値オブジェクトです。ただし、連邦準備制度理事会は、それぞれの独自の法案について懸念している可能性があります。このコンテキストでは、各法案はエンティティになります。

エンティティ:ほとんどの航空会社は、すべてのフライトで各座席を一意に区別しています。このコンテキストでは、各座席がエンティティです。ただし、Southwest Airlines、EasyJet、および Ryanair はすべての座席を区別していません。すべての座席は同じです。このコンテキストでは、座席は実際には値オブジェクトです。

于 2021-07-02T16:17:03.353 に答える