Value vs Entity-Objekte (Domain Driven Design)


90

Ich habe gerade angefangen, DDD zu lesen. Ich kann das Konzept von Entity vs Value-Objekten nicht vollständig erfassen. Kann jemand bitte die Probleme (Wartbarkeit, Leistung usw.) erläutern, mit denen ein System konfrontiert sein könnte, wenn ein Value-Objekt als Entity-Objekt entworfen wird? Beispiel wäre toll ...


2
Hier schrieb ich eine vollständige (IMO) Liste der Unterschiede zwischen den beiden: Enterprisecraftsmanship.com/2016/01/11/…
Vladimir

Antworten:


107

Auf das Wesentliche reduziert, ist Identität für Entitäten wichtig, für Wertobjekte jedoch nicht. Zum Beispiel ist der Name einer Person ein Wertobjekt. Eine Kundenentität kann aus einem Kundennamen (Wertobjekt), List <Order> OrderHistory (Liste der Entitäten) und möglicherweise einer Standardadresse (normalerweise ein Wertobjekt) bestehen. Die Kundeneinheit hätte eine ID, und jede Bestellung hätte eine ID, ein Name jedoch nicht. Im Allgemeinen spielt die Identität einer Adresse innerhalb des Objektmodells wahrscheinlich keine Rolle.

Wertobjekte können normalerweise als unveränderliche Objekte dargestellt werden. Das Ändern einer Eigenschaft eines Wertobjekts zerstört im Wesentlichen das alte Objekt und erstellt ein neues, da Sie sich nicht so sehr mit Identität als mit Inhalt befassen. Richtig, die Equals-Instanzmethode für Name würde "true" zurückgeben, solange die Eigenschaften des Objekts mit den Eigenschaften einer anderen Instanz identisch sind.

Das Ändern eines Attributs einer Entität wie "Kunde" zerstört den Kunden jedoch nicht. Eine Kundenentität ist normalerweise veränderlich. Die Identität bleibt gleich (mindestens sobald das Objekt beibehalten wurde).

Sie erstellen wahrscheinlich Wertobjekte, ohne es zu merken. Jedes Mal, wenn Sie einen Aspekt einer Entität darstellen, indem Sie eine feinkörnige Klasse erstellen, haben Sie ein Wertobjekt. Beispielsweise wäre eine Klasse IPAddress, die einige Einschränkungen für gültige Werte aufweist, jedoch aus einfacheren Datentypen besteht, ein Wertobjekt. Eine EmailAddress kann eine Zeichenfolge oder ein Wertobjekt mit eigenen Verhaltensweisen sein.

Es ist durchaus möglich, dass selbst Elemente, die eine Identität in Ihrer Datenbank haben, keine Identität in Ihrem Objektmodell haben. Der einfachste Fall ist jedoch eine Zusammenstellung einiger Attribute, die zusammen Sinn machen. Sie möchten wahrscheinlich nicht Customer.FirstName, Customer.LastName, Customer.MiddleInitial und Customer.Title haben, wenn Sie diese zusammen als Customer.Name zusammenstellen können. Es werden wahrscheinlich mehrere Felder in Ihrer Datenbank sein, wenn Sie über Persistenz nachdenken, aber Ihr Objektmodell kümmert sich nicht darum.


Wo passen nicht gemeinsam genutzte veränderbare Objekte hin? Wenn im gesamten Universum nur ein Verweis auf ein Objekt existiert, ist die Identität des Objekts irrelevant, selbst wenn es veränderbar ist. Aus meiner Sicht ist ein Ding eine Entität, wenn es eine Referenz gibt, die verwendet werden könnte, um einen Aspekt des Zustands zu beobachten, der sich ändern könnte, ohne dass diese Referenz verwendet wurde, um ihn zu ändern . Wenn ein Ding nicht an die Außenwelt gebunden ist und entweder unveränderlich ist oder nur ein Hinweis darauf irgendwo im Universum existiert, kann das obige Szenario nicht auftreten und es ist ein Wert.
Supercat

So etwas wie ein int[1]kann ein nicht gemeinsam genutzter veränderlicher Wert sein, ein gemeinsam nutzbarer unveränderlicher Wert (wenn keines der Dinge, die Referenzen enthalten, jemals darauf schreiben wird) oder eine Entität (wenn zwei oder mehr Referenzen existieren und eine davon zum Schreiben verwendet werden kann Werte, die mit dem anderen gelesen werden können). Leider ist mir keine Sprachunterstützung in Java oder .NET bekannt, um zu verhindern, dass Klassenobjekte, die veränderbare Werte kapseln, versehentlich zu Entitäten werden.
Supercat

@supercat, Wenn Sie keine direkte einfache Unterstützung meinen, würde ich zustimmen, aber ich tue dies, indem ich den öffentlichen Zugriff auf Konstruktoren eliminiere, nur statische Fabriken verwende, um neue Instanzen zu erstellen, und den gesamten Zugriff auf den Status durch schreibgeschützte Eigenschaften einschränke (keine Setter). .
Charles Bretana

35

Jedes Objekt, das gemeinsam durch alle Attribute definiert wird, ist ein Wertobjekt. Wenn sich eines der Attribute ändert, haben Sie eine neue Instanz eines Wertobjekts. Aus diesem Grund werden Wertobjekte als unveränderlich definiert.

Wenn das Objekt nicht durch alle Attribute vollständig definiert ist, gibt es eine Teilmenge von Attributen, aus denen die Identität des Objekts besteht. Die verbleibenden Attribute können sich ändern, ohne das Objekt neu zu definieren. Diese Art von Objekt kann nicht unveränderlich definiert werden.

Eine einfachere Möglichkeit zur Unterscheidung besteht darin, Wertobjekte als statische Daten zu betrachten, die sich niemals ändern, und Entitäten als Daten, die sich in Ihrer Anwendung entwickeln.


7

Werttypen:

  • Werttypen existieren nicht alleine, abhängig von Entitätstypen.
  • Das Werttypobjekt gehört zu einem Entitätstypobjekt.
  • Die Lebensdauer einer Werttypinstanz ist durch die Lebensdauer der Instanz der besitzenden Entität begrenzt.
  • Drei Werttypen: Basic (primitive Datentypen), Composite (Adresse) und Collection (Map, List, Arrays)

Entitäten:

  • Entitätstypen können eigenständig existieren (Identität)
  • Eine Entität hat ihren eigenen Lebenszyklus. Es kann unabhängig von einer anderen Einheit existieren.
  • Zum Beispiel: Person, Organisation, Hochschule, Mobil, Zuhause usw. Jedes Objekt hat seine eigene Identität

Nicht verwandt mit DDD :(
HydTechie

6

Ich weiß nicht, ob das Folgende richtig ist, aber ich würde sagen, dass wir im Fall eines Adressobjekts dieses als Wertobjekt anstelle einer Entität verwenden möchten, da Änderungen an der Entität sich auf alle verknüpften Objekte auswirken würden ( eine Person zum Beispiel).

Nehmen Sie diesen Fall: Sie leben mit einigen anderen Menschen in Ihrem Haus. Wenn wir Entität für Adresse verwenden würden, würde ich argumentieren, dass es eine eindeutige Adresse geben würde, mit der alle Personenobjekte verknüpft sind. Wenn eine Person auszieht, möchten Sie ihre Adresse aktualisieren. Wenn Sie die Eigenschaften der Adressentität aktualisieren würden, hätten alle Personen eine andere Adresse. Im Fall eines Wertobjekts könnten wir die Adresse nicht bearbeiten (da sie unveränderlich ist) und wären gezwungen, eine neue Adresse für diese Person anzugeben.

Klingt das richtig? Ich muss sagen, dass ich nach dem Lesen des DDD-Buches auch immer noch verwirrt über diesen Unterschied war / bin.

Wie würde dies in der Datenbank modelliert? Hätten Sie alle Eigenschaften des Adressobjekts als Spalten in der Personentabelle oder würden Sie eine separate Adresstabelle erstellen, die auch eine eindeutige Kennung hätte? Im letzteren Fall hätten die im selben Haus lebenden Personen jeweils eine andere Instanz eines Adressobjekts, aber diese Objekte wären bis auf ihre ID-Eigenschaft identisch.


1
"Nehmen Sie diesen Fall: Sie leben mit einigen anderen Personen in Ihrem Haus. Wenn wir Entität als Adresse verwenden würden, würde ich argumentieren, dass es eine eindeutige Adresse geben würde, mit der alle Personenobjekte verknüpft sind." Ich denke, jeder dieser Leute hat seine eigene Adresse, aber sie sind zufällig gleich (es ist, als ob jeder von ihnen eine 5-Dollar-Banknote haben kann, aber das bedeutet nicht, dass es dieselbe Banknote ist)
Prokurors

"aber das bedeutet nicht, dass es sich um dieselbe Banknote handelt" - Ich denke, dies hängt davon ab, ob man der Banknote zusätzliche Eigenschaften zuweist oder nicht (z. B. Ausgabedatum, physischer Ort im Raum usw.); sonst wären sie gleich. Und ich denke, das gilt auch für Software: Die Adresse ist gleich oder nicht, abhängig von den Eigenschaften, die wir berücksichtigen müssen / möchten.
Adrrc

4

Die Adresse kann eine Entität oder ein Wertobjekt sein, das vom Geschäftsprozess abhängt. Das Adressobjekt kann eine Entität in einer Kurierdienstanwendung sein, die Adresse kann jedoch in einer anderen Anwendung ein Wertobjekt sein. Bei der Kurieranwendung ist die Identität für das Adressobjekt von Bedeutung


2

Ich habe in einem anderen Thread danach gefragt und ich denke, ich bin immer noch verwirrt. Ich kann Leistungsüberlegungen mit Datenmodellierung verwechseln. In unserer Katalogisierungsanwendung ändert sich ein Kunde erst, wenn dies erforderlich ist. Das klingt dumm - aber das "Lesen" von Kundendaten ist weitaus größer als das "Schreiben", und da viele, viele Webanfragen alle auf den "aktiven Satz" von Objekten treffen, möchte ich Kunden nicht immer wieder laden. Ich war also auf dem Weg zu einem unveränderlichen Weg für das Kundenobjekt - laden Sie es, speichern Sie es im Cache und stellen Sie dasselbe für 99% der (Multithread-) Anforderungen bereit, die den Kunden sehen möchten. Wenn ein Kunde etwas ändert, lassen Sie einen "Editor" einen neuen Kunden erstellen und den alten ungültig machen.

Ich mache mir Sorgen, wenn viele Threads dasselbe Kundenobjekt sehen und es veränderbar ist. Wenn ein Thread beginnt, sich zu ändern, kommt es in den anderen zu Chaos.

Meine Probleme sind jetzt: 1) Ist dies vernünftig und 2) Wie geht das am besten, ohne viel Code über die Eigenschaften zu duplizieren?


1

3 Unterscheidung zwischen EntitiesundValue Objects

  • Kennung vs. strukturelle Gleichheit: Entitäten haben Kennung, Entitäten sind gleich, wenn sie dieselbe Kennung haben. Wertobjekte jenseits der Hand haben strukturelle Gleichheit. Wir betrachten zwei Wertobjekte als gleich, wenn alle Felder gleich sind. Wertobjekte können keine Kennung haben.

  • Veränderbarkeit vs. Unveränderlichkeit: Wertobjekte sind unveränderliche Datenstrukturen, während sich Entitäten während ihrer Lebensdauer ändern.

  • Lebensdauer: Wertobjekte sollten zu Entitäten gehören


1

In einem sehr einfachen Satz kann ich sagen, wir haben drei Arten von Gleichheit:

  • Identifikatorgleichheit : Eine Klasse hat eine ID-Datei und zwei Objekte werden mit ihrem ID-Feldwert verglichen.
  • Referenzgleichheit : Wenn eine Referenz auf zwei Objekte dieselbe Adresse im Speicher hat.
  • Strukturelle Gleichheit : Zwei Objekte sind gleich, wenn alle Mitglieder übereinstimmen.

Die Identifikatorgleichheit bezieht sich nur auf die Entität und die strukturelle Gleichheit bezieht sich nur auf das Wertobjekt. Tatsächlich haben Wertobjekte keine ID und wir können sie austauschbar verwenden. Außerdem müssen Wertobjekte unveränderlich sein und Entitäten können veränderbar sein, und Wertobjekte haben keine Nein-Tabelle in der Datenbank.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.