Passen unveränderliche Objekte und DDD zusammen?

18

Stellen Sie sich ein System vor, das DDD verwendet (auch: jedes System, das ORM verwendet). In nahezu jedem Anwendungsfall besteht der Sinn eines jeden Systems darin, diese Domänenobjekte realistisch zu manipulieren. Ansonsten gibt es keine wirklichen Auswirkungen oder Ziele.

Wenn Sie ein unveränderliches Objekt ändern, wird nach der Beibehaltung des Objekts ein neuer Datensatz generiert, wodurch die Datenquelle stark aufgebläht wird (es sei denn, Sie löschen vorherige Datensätze nach Änderungen).

Ich kann den Vorteil der Verwendung unveränderlicher Objekte erkennen, aber in diesem Sinne kann ich nie einen nützlichen Fall für die Verwendung unveränderlicher Objekte erkennen. Ist das falsch?

Steven Evers
quelle

Antworten:

16

Die Berechnung mit unveränderlichen Objekten (wie bei der funktionalen Programmierung) bedeutet nicht unbedingt, dass jedes erzeugte Objekt erhalten bleibt!

Steven A. Lowe
quelle
Ich sehe jedoch keinen Fall, in dem in diesem Szenario unveränderliche Objekte verwendet werden - sie wären also für keinen bestimmten Zweck da. Liege ich falsch?
Steven Evers
1
Ich dachte, dass die unveränderlichen Objekte für Zwischenberechnungen nützlich sein würden (in parallelen Threads)
Steven A. Lowe
11

Bedeutet unveränderlich in der Domain, dass es unveränderlich in der Datenbank sein muss? Angenommen, der Kunde hat immer eine Adresse:

customer.address = new Address('My Castle', 'Kings street');
customer_repo.save(customer);

Jetzt wird die folgende SQL ausgeführt, wenn die Kunden-ID 1 ist:

INSERT INTO addresses (customer_id, name, street)
VALUES (1, 'My Castle', 'Kings street');

jetzt wird folgende änderung an der adresse vorgenommen:

customer.address = new Address('Pauper palace', 'Outlands');
customer_repo.save(customer);

und die Persistenzschicht, die sehr klug ist, führt den folgenden SQL-Code aus:

UPDATE addresses SET name='Pauper palance', street='Outlands'
WHERE customer_id = 1;

Auf diese Weise vermeiden Sie den Overhead einer separaten DELETE AND INSERT-Anweisung. Ich denke auch, dass einige RDBMS INSERT REPLACE oder so haben. MySQL hat REPLACE .

andho
quelle
+1 Ich stimme dem allgemeinen Prinzip zu: Ich verstehe nicht, warum unveränderliche Domänenobjekte unbedingt unveränderliche DB-Zeilen bedeuten müssen.
Andres F.
? Im obigen Fall , wenn wir jemals die Stadt Attribut der Adressklasse zu ändern , für einen bestimmten Kunden benötigen , wie wir damit umgehen würden, sei weiterhin angenommen Kunde mehr Adressen , so dass es aa one to many Beziehung Schiff zwischen Kunden und Adressen haben könnte
Sudarshan
1
@Sudarshan Dies ist nur eine Möglichkeit, ein 'unveränderliches Wertobjekt' zu erstellen, das in der Datenbank nicht wirklich unveränderlich ist. Aus Performancegründen. Jede Situation muss natürlich speziell behandelt werden. Ich bevorzuge jetzt Event Sourcing für meine Domain, bin aber irgendwie süchtig danach.
Andho
@Sudarshan, um Ihre Frage speziell zu beantworten. Sie führen nur eine Aktualisierungsabfrage aus, mit der die Zeile auf den neuen Wert aktualisiert wird. Wenn es sich um eine Eins-zu-Viele-Adresse handelt, haben die Adressen im Kunden-Gesamtstamm eine Art Kennung, mit der sie in der Datenbank eindeutig identifiziert werden können. Diese Kennung und customer_id werden dann verwendet, um diese Zeile in der Tabelle 'address' zu aktualisieren.
Andho
@andho "Dies ist nur eine Möglichkeit, ein 'unveränderliches Wertobjekt' zu erstellen, das in der Datenbank nicht wirklich unveränderlich ist." Das hat meinen Tag wirklich zum Dank gemacht
Sudarshan
6

In DDD sind unveränderliche Objekte fast mit Wertobjekten gleichzusetzen. Diese Objekte sind keine Entitäten, sie haben keine Identität. Daher behalte ich Wertobjekte immer als Spalten der Entität bei, in der sie enthalten sind (mit N / Hibernate können Sie hierfür Components verwenden). Sie haben keinen eigenen Tisch.

guillaume31
quelle
4

Dies hängt davon ab, wie das unveränderliche Objekt in der Datenbank abgebildet wird. Wenn es sich nur um eine Komponente wie DateTime (aus der Joda Time-Bibliothek) handelt, führt das Ändern des Werts zu einer Aktualisierung und nicht zu einer Einfügung. Wenn die Unveränderlichkeit jedoch komplexer ist und eine Zeile in einer Tabelle erfordert, besteht das Problem der Aufblähung.

Ich nehme an, obwohl dies ein schwaches Argument ist, könnten Sie auf diese Weise einen Audit-Trail implementieren. Jede Änderung an der Datei kann durch die Einsätze verfolgt werden. Es gibt jedoch viele bessere Möglichkeiten, dies zu tun.

Alles in allem scheint das Vorhandensein unveränderlicher Domänenobjekte (statt nur ihrer Komponenten) eine gewisse Inkongruenz mit der Persistenz zu haben.

Gary Rowe
quelle
Keineswegs. Komponenten sind sehr nützlich, da sie die Zusammensetzung von Domänenobjekten von denselben zugrunde liegenden Daten unterscheiden können. Die Probleme ergeben sich aus der Durchsetzung der Unveränderlichkeit. Persönlich würde ich Domänenobjekte (mit Ausnahme der Primärschlüsselfelder) als veränderlich behandeln und es einfach halten.
Gary Rowe
"Alles in allem scheint das Vorhandensein unveränderlicher Domänenobjekte (statt nur ihrer Komponenten) mit der Beständigkeit ein wenig nicht übereinzustimmen." Wo müssten Ihrer Meinung nach Wertobjekte liegen, die nicht als Komponenten modelliert werden sollten (Hibernate-Terminologie)? --- Entschuldigung, ich hatte meinen letzten Kommentar falsch geschrieben und ihn daher gelöscht.
Sudarshan
Vermeiden Sie Komponenten, wenn eine einzelne Entität vollständig durch eine Zeile dargestellt wird und keine Daten von einem anderen Domänenobjekt gemeinsam genutzt werden.
Gary Rowe
4

Das kommt auf die Domain an. DDD gibt nicht an, dass das Programmierparadigma objektorientiert ist. Das objektorientierte Paradigma eignet sich jedoch gut für die typische Anwendung, die in einer Datenbank beibehalten werden muss.

DDD gibt einfach an, dass Sie Ihre Software um ein Domänenmodell herum erstellen sollten, das das tatsächliche Problem darstellt, das die Software zu lösen versucht. Wenn dieses Problem beispielsweise mathematischer Natur wäre, dann wäre die Implementierung der Domänenschicht unter Verwendung von funktionaler Programmierung und unveränderlichen Datenstrukturen sehr sinnvoll.

Wenn andererseits das Problem eher eine typische Unternehmensanwendung ist und Sie unveränderliche Objektstrukturen für alle Ihre Domänenobjekte verwenden, würde ich argumentieren, dass Sie DDD nicht folgen. Ich kann mindestens zwei Argumente vorbringen:

  • Ihre Implementierung repräsentiert kein Domänenmodell Ihrer Problemdomäne. Ihre Problemdomäne besteht in diesem Fall aus Entitäten, deren Status geändert werden muss. Und so haben Sie es nicht umgesetzt.

  • Sie haben keine allgegenwärtige Sprache. Die Sprache und die Konzepte im Domain-Modell entsprechen nicht dem, was die Domain-Experten verwenden.

Hinweis: DDD verwendet gegebenenfalls unveränderliche Objekte, die nur als Wertobjekte bezeichnet werden.

Ich sage also nicht, dass Sie keine Datenbankanwendung mit rein funktionalen Datenstrukturen erstellen können, und ich sage auch nicht, dass Sie das nicht sollten. Ich glaube einfach nicht, dass man es je nach Art der Anwendung als DDD bezeichnen kann

Pete
quelle
Peter, tolle Antwort. Sehen Sie sich meine Frage hier an: stackoverflow.com/questions/13783666/… und helfen Sie mir, mein Problem herauszufinden. Ich denke, Objekte mit unveränderlichem Wert eignen sich hervorragend für Software, die nicht unternehmensbezogen sind. Die meisten Objekte von Unternehmensanwendungen können meiner Meinung nach geändert werden. Stellen Sie sich vor, Sie haben ein unveränderliches, tief verschachteltes Wertobjekt ... ContactInfo-> PhysicalLocation-> Address und Sie möchten die Postleitzahl aktualisieren ... Das Erstellen des gesamten Objektdiagramms scheint mir ein Antichrist zu sein, nicht nur ein Antipattern. was denkst du?
Pepito Fernandez
3

Wenn Sie ein ORM wie Ruhezustand / Ruhezustand verwenden, können Sie Ihre Kaskadenoption so einstellen, dass verwaiste Objekte automatisch gelöscht werden. Wenn eine Person ein Wertobjekt Adresse hat, wird beim Ändern der Adresse die neue gespeichert und die alte gelöscht, da sie jetzt verwaist ist.

Mike Rowley
quelle
0

Wertobjekte sind in DDD fast immer unveränderlich, und das Flyweight-Muster kann verwendet werden, um die Duplizierung dieses Wertobjekts im Arbeitsspeicher so gering wie bei .NET mit Zeichenfolgen zu halten. Der Hauptnachteil ist das Gedächtnis auf der einen Seite und auf der anderen Seite die kreative Effizienz. Mit dem Fliegengewichtmuster muss ein wertebasierter Vergleich durchgeführt werden, um zu bestimmen, ob sich ein neues oder wiederhergestelltes Wertobjekt bereits im Fliegengewicht-Cache befindet. Jeder andere Vergleich nach diesem Punkt kann jedoch im Allgemeinen sicher als Referenz durchgeführt werden, da eine einzelne Instanz erzwungen wird. Unabhängig davon, ob Fliegengewicht verwendet wird oder nicht, werden Wertobjekte immer noch unveränderlich gemacht, da sie nur über eine eigene Identität verfügen und daher durch Ändern ihres Werts ihre Identität geändert wird.

jpierson
quelle
-1

Es gibt eine andere Möglichkeit, unveränderliche Objekte zu verwenden ...

Anstatt die Werte 5.0, 6.0, 7.0, 8.0 zu speichern und den gesamten Datensatz jedes Mal zu kopieren, können Sie Folgendes speichern: 5.0, +1.0, +1.0, +1.0 und dann Abhängigkeiten korrekt erstellen, um die Sequenz 5.0 zu rekonstruieren , 6.0, 7.0, 8.0. Auf diese Weise nehmen kleine Änderungen nur wenig Speicherplatz in Anspruch ...

tp1
quelle