DDD- und Wertobjekte. Sind veränderbare Wertobjekte ein guter Kandidat für Non Aggr. Stammentität?

9

Hier ist ein kleines Problem

Haben Sie eine Entität mit einem Wertobjekt. Kein Problem. Ich ersetze ein Wertobjekt durch ein neues, dann füge nhibernate den neuen Wert ein und verwaise den alten und lösche ihn dann. Ok, das ist ein Problem.

Versichert ist mein Unternehmen in meiner Domain. Er hat eine Sammlung von Adressen (Wertobjekten). Eine der Adressen ist die MailingAddress. Wenn wir die Postanschrift aktualisieren möchten, sagen wir, die Postleitzahl war falsch. Nach der Doktrin von Mr. Evans müssen wir das alte Objekt durch ein neues ersetzen, da es unveränderlich ist (ein Wertobjekt, oder?).

Wir möchten die Zeile du jedoch nicht löschen, da die PK dieser Adresse eine FK in einer MailingHistory-Tabelle ist. Nach der Doktrin von Mr. Evans sind wir hier also ziemlich durcheinander. Es sei denn, ich mache meine Adressen zu Entitäten, damit ich sie nicht "ersetzen" und einfach ihre Postleitzahl aktualisieren muss, wie in den alten guten Tagen.

Was würden Sie mir in diesem Fall vorschlagen? So wie ich es sehe, sind ValueObjects nur nützlich, wenn Sie eine Gruppe von Datenbanktabellenspalten (Komponente in nhibernate) kapseln möchten. Alles, was eine Persistenz-ID in der Datenbank enthält, ist besser geeignet, um sie zu einer Entität (nicht unbedingt zu einem aggregierten Stamm) zu machen, damit Sie ihre Mitglieder aktualisieren können, ohne das gesamte Objektdiagramm neu zu erstellen, insbesondere wenn es sich um ein tief verschachteltes Objekt handelt.

Stimmen Sie zu? Darf Mr. Evans ein veränderbares Wertobjekt haben? Oder ist ein veränderbares Wertobjekt ein Kandidat für eine Entität?

Vielen Dank

Pepito Fernandez
quelle
2
Gibt es so etwas wie "veränderbares Wertobjekt"? Ich hatte immer den Eindruck Wert Objekte sind unveränderlich.
Herby
@herby Ich denke, Sie könnten ein veränderbares Objekt haben, das ein DDD-Wertobjekt im Code darstellt, aber Sie müssten berücksichtigen, dass es nach dem Mutieren des Objekts nicht mehr auf dasselbe logische DDD-Wertobjekt verweist, sondern auf ein neues. Dies mag wünschenswert sein, ist aber ein Rezept für Verwirrung, da es eine kluge Konvention ist, Wertobjekte im Code unveränderlich zu machen.
MattDavey

Antworten:

8

Alles, was eine Identität hat , sollte eine Entity, und alles sein, der sich nicht eine Identität haben , ist ein einfacher Wert, also ein Wertobjekt.

Um Martin Fowler zu zitieren (der wiederum Eric Evans spricht)

  • Entität: Objekte mit einer bestimmten Identität , die sich durch die Zeit und verschiedene Darstellungen zieht. Sie hören auch diese sogenannten "Referenzobjekte".
  • Wertobjekt: Objekte, die wichtig sind, haben nur die Kombination ihrer Attribute.

Grund, Ihre Adresse zu einem Wertobjekt zu machen:

Wenn Ihre Adresse veränderlich ist, werden Sie wahrscheinlich am Ende Ihren Mailing-Verlauf vermasseln. Wenn Sie beispielsweise Artikel an einen Kunden versenden, können Sie nicht sicher sein, an welche Adresse Sie in der Vergangenheit tatsächlich etwas versendet haben, wenn die Adresse, auf die sich Ihre MailingHistory-Tabelle bezieht, geändert wurde.

Der MailingHistory-Eintrag Wir haben A764 an Adresse 657 verschickt. Dies könnte bedeuten, dass wir gestern Artikel A764 nach Boston und morgen Artikel A764 nach New York verschickt haben .

Wenn die Postanschrift geändert werden muss, muss die alte nicht gelöscht werden . Behalten Sie es bei und markieren Sie es als inaktiv und das neue als aktiv .


Natürlich können Sie Ihre Adresse als Entität behandeln, aber nur beim Aktualisieren wird der tatsächliche Ort, auf den sich die Adresse bezieht, nicht geändert, sodass nur Tippfehler korrigiert werden können.

Wenn Sie sicher sind, dass Sie dies sicherstellen können, ist die Verwendung einer Entität möglich.


Die beste Lösung ist meiner Meinung nach jedoch, keine Adressentität in Ihrem Mailing-Verlauf zu referenzieren, sondern die spezifische Adresse direkt in Ihrer Mailing-Verlaufstabelle zu speichern (im Grunde genommen die Daten der Adresse zu kopieren).

Auf diese Weise wissen Sie immer, wohin Sie Ihre Sachen verschickt haben (oder was auch immer Sie verschicken), und da Sie eine veränderbare Entität verwenden würden, wird Ihre Adresstabelle nicht überladen.

Ich habe mit / an mehreren ERP-Systemen gearbeitet, und fast alle haben diesen Ansatz verwendet.

Sie werden einige Redundanz in Ihrer Datenbank haben, aber es ist meiner Meinung nach der pragmatischste Weg.

Faultier
quelle
Dies ist wahrscheinlich die kopfschmerzfreieste Lösung. Nur wenn Sie erwarten, dass zukünftige Kommunikationskanäle zusätzliche Spalten erfordern und Ihre Datenbank zu groß ist, ALTERkann die Verwendung von Entitäten in separaten Tabellen erforderlich werden. Dies erfordert wiederum Strategien wie "Immer die neueste Adresse / Telefon / E-Mail eingeben" in Ihren SELECTAnfragen, die schwierig zu warten und effizient zu halten sind. Halte es einfach, wenn es überhaupt möglich ist.
Timo
@Timo "Immer der neuesten Adresse / Telefon / E-Mail beitreten" ist nicht schwer, wenn Sie Ihre Daten ein wenig denormalisieren, indem Sie einfach ein active-flag hinzufügen . Natürlich müssen Sie sicherstellen, dass Sie and active = trueIhre Joins immer verwenden , das Flag auf dem neuesten Stand halten und Ihrer Tabelle einen Contraint hinzufügen, damit z. B. nur eine E-Mail für jeden Kunden dieses Flag auf true setzen kann.
Faultier
Dies führt das Problem der Deaktivierung des vorherigen ein. Wenn Sie das "aktuelle" Adressobjekt Ihrer Instanz im Code ersetzt haben und zu Ihrem Datenzugriffscode wechseln, weiß es nicht, (1) ob es ein neues gibt oder nicht, (2) was das potenzielle alte ist jemand war. Daher muss jeder Speichervorgang etwas kompliziertes ausführen, z. B. "Zuerst alle zugehörigen Adressen in der Datenbank deaktivieren" und dann die aktuelle Adresse mit speichern active=true. Das würde ich nicht einfach nennen, genau deshalb mag ich Ihre Lösung.
Timo
2

Ich sehe 2 Dinge:

  1. Ist eine Änderung der Postleitzahl in Ordnung, um einen Verlaufsdatensatz zu beeinflussen? Ich denke, es wäre logisch, wenn der Verlaufsdatensatz auf die alte, unveränderte Adresse verweist, sodass Sie wissen, dass Sie ihn an eine falsche Adresse senden.

  2. In dem Moment, in dem MailingHistory FK für die Adresse hat, ist die Adresse kein Wertobjekt mehr und wird zu einer Entität. Wertobjekte haben keine Identität, sodass andere Entitäten auf diese Identität verweisen können. Sie können Adressen in einer einzelnen Tabelle haben, auf die andere Tabellen verweisen. Der einzige Effekt ist jedoch die Platzersparnis. Wenn aus Sicht der Domäne zwei Entitäten denselben Wertobjekttyp referenzieren, teilen sie keinerlei Informationen.

Euphorisch
quelle
2

IMO ist das Adressobjekt eine Entität in Ihrer Domain. Es wird von mehreren Entitäten gemeinsam genutzt, hat eine eigene Identität und ist systemweit einzigartig.

Evans sagt:

Ein Objekt, das hauptsächlich durch seine Identität definiert wird, wird als Entität bezeichnet.

Margabit
quelle
Domain-Identitäten haben meines Wissens nichts mit Persistenz-Identität zu tun. Nach Mr. Evans Buch.
Pepito Fernandez
Du hast recht. Ich bearbeite meine Antwort. Was ich damit meine ist, dass die Objektadresse in dieser bestimmten Domäne eine Rolle spielt, sie ist eindeutig. IMO ist der Fremdschlüssel und der Primärschlüssel ein Zeichen dafür, dass es sich tatsächlich um ein eindeutiges Objekt in der gesamten Domäne handelt, sodass es eine Identität hat.
Margabit
1
"das Adressobjekt ... hat seine eigene Identität" - welches Attribut einer Adresse identifiziert es eindeutig? Kein einzelnes Attribut einer Adresse ist eindeutig, aber die Kombination von Attributen dient als Identität. Dies ist
genau
@MattDavey: Es ist eine gute Schlussfolgerung, aber ich bin verwirrt, als Tony sagt "Wir wollen die Zeile du nicht löschen, weil die PK dieser Adresse eine FK in einer MailingHistory-Tabelle ist". Dies bedeutet für mich, dass das Adressobjekt auch eine Bedeutung außerhalb des Aggregats 'Versichert' hat. Was mich darauf hinweist, dass das 'Address'-Objekt kein ValueObject sein sollte. Was denkst du?
Margabit
Könnten wir sagen, dass Wertobjekte ausnahmslos eine hundertprozentige Komposition (UML) des übergeordneten Elements sind? Außerdem wäre ein Wertobjekt ohne seine Eltern nicht sinnvoll und kann nicht zwischen Eltern geteilt werden?
Sudarshan