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 ...
90
Antworten:
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.
quelle
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.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.
quelle
Werttypen:
Entitäten:
quelle
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.
quelle
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
quelle
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?
quelle
3 Unterscheidung zwischen
Entities
undValue 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
quelle
In einem sehr einfachen Satz kann ich sagen, wir haben drei Arten von Gleichheit:
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.
quelle