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
quelle
Antworten:
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)
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.
quelle
ALTER
kann die Verwendung von Entitäten in separaten Tabellen erforderlich werden. Dies erfordert wiederum Strategien wie "Immer die neueste Adresse / Telefon / E-Mail eingeben" in IhrenSELECT
Anfragen, die schwierig zu warten und effizient zu halten sind. Halte es einfach, wenn es überhaupt möglich ist.active
-flag hinzufügen . Natürlich müssen Sie sicherstellen, dass Sieand active = true
Ihre 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.active=true
. Das würde ich nicht einfach nennen, genau deshalb mag ich Ihre Lösung.Ich sehe 2 Dinge:
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.
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.
quelle
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:
quelle