DDD - Übergang des Entitätsstatus

8

Betrachten Sie das folgende vereinfachte Beispiel:

%Vor%

Der Klassenstatus wird direkt innerhalb des Domänenobjekttickets verwendet. Später im Lebenszyklus des Tickets können andere Zustände eingestellt werden.

Das Ticket wird in einer Ticket-Tabelle sowie in TicketState gespeichert. Innerhalb der DB hat das Ticket also einen Fremdschlüssel für die Ticketstatus-Tabelle.

Wie lade ich beim Festlegen des entsprechenden Status in meiner Entity die Statusinstanz aus der Datenbank? Muss ich ein Repository in die Entität einfügen? Muss ich für solche Fälle ein Framework wie Castle verwenden? Oder gibt es bessere Lösungen, vielleicht den Staat von außen zu passieren?

%Vor%

Gibt es Best Practices? Bis jetzt habe ich noch kein Framework zur Injection von Abhängigkeiten oder irgendetwas verwendet und behalte alles aus meiner Domäne heraus.

Eine weitere Annäherung:

%Vor%     
Chris 10.02.2010, 23:28
quelle

3 Antworten

4

Das Ticket würde keinen Verweis auf ein Repository haben. Es würde eine Eins-zu-Eins-Beziehung mit TicketState haben, und das TicketRepository würde einfach den JOIN durchführen und die Werte dem Ticket zuordnen.

Wenn ich Modellobjekte erstelle, mache ich ihnen normalerweise nicht bewusst, ob sie persistent sind oder nicht, so dass ihnen kein Repository hinzugefügt wird. Das Repository behandelt alle CRUD-Operationen.

Einige Leute widersprechen dem und sagen, dass es zu einem anämischen Domänenmodell führt; vielleicht bist du einer von ihnen. Wenn dies der Fall ist, injizieren Sie das Repository in Ihr Ticket-Objekt, aber fordern Sie es einfach auf, den JOIN-Befehl auszuführen und ein Ticket zurückzugeben, dessen Status aufgefüllt ist. Wenn Sie eine Tabelle einfügen oder aktualisieren, müssen Sie zwei Tabellen als einzelne Arbeitseinheit ändern. Stellen Sie daher sicher, dass Transaktionen aktiviert sind.

Der Grund, warum ich CRUD-Ops außerhalb des Domänenmodellobjekts haben möchte, ist, dass es normalerweise nicht das einzige Domänenobjekt ist, das an einem Anwendungsfall oder einer Transaktion beteiligt ist. Zum Beispiel könnte Ihr einfacher "Kauf Ticket" Anwendungsfall ein Ticket-Objekt haben, aber es muss auch einige andere Objekte geben, die sich mit Reservierungen und Sitz- und Hauptbuch und Inventar von Gepäck und allen möglichen anderen Dingen beschäftigen. Sie möchten mehrere Modellobjekte wirklich als einzelne Arbeitseinheit beibehalten. Nur die Serviceschicht kann wissen, wann ein Modellobjekt eigenständig agiert und wann es Teil eines größeren, größeren Plans ist.

Aktualisierung:

Ein weiterer Grund, warum mir die Idee, ein Modellobjekt mit einem DAO zu injizieren, damit es Persistenzaufgaben bewältigen kann, nicht gefällt, ist das Trashing von Layern und die zyklische Abhängigkeit, die es einführt. Wenn Sie das Modell von Referenzen auf Persistenzklassen freihalten, können Sie sie verwenden, ohne die andere Ebene aufzurufen. Es ist eine einseitige Abhängigkeit; Persistenz kennt Modell, aber Modell weiß nichts über Persistenz.

Injizieren Sie die Persistenz in das Modell und sie sind zyklisch voneinander abhängig. Sie können keines der beiden ohne das andere verwenden oder testen. Keine Schichtung, keine Trennung von Bedenken.

    
duffymo 10.02.2010, 23:37
quelle
1

Diese Antwort folgt hoffentlich auf Duffymos.

In einer DDD-Ansicht der Welt ist Ihr TicketState eine Entität, die Teil des Ticket-Aggregats ist (wobei ein Ticket das aggregierte Stammverzeichnis ist).

Anschließend behandelt Ihr TicketRepository sowohl Tickets als auch TicketStates.

Wenn Sie ein Ticket von der Persistenzschicht abrufen, erlauben Sie Ihrem TicketRepository, den Status aus der Datenbank abzurufen und auf dem Ticket korrekt zu setzen.

Wenn Sie ein Ticket neu erstellen (ich denke), müssen Sie die Datenbank noch nicht anfassen. Wenn das Ticket schließlich beibehalten wird, nehmen Sie den neuen Status des Tickets und führen es korrekt fort.

Ihre Domänenklassen sollten nichts über das Datenbankmodell wissen müssen, das sich um den Zustand kümmert, sie sollten nur über die Zustandsansicht des Domänenmodells informiert sein. Ihr Repository ist dann für dieses Mapping verantwortlich.

    
David Hall 10.02.2010 23:53
quelle
0

Für mich muss ein einfaches Schlüssel / Wert-Paar, das den Status in der Datenbank (oder einem anderen Persistenzmedium) darstellt, nicht als solches in der Domäne modelliert werden. In der Domäne würde ich TicketState zu einer Enumeration machen und es dem ITicketRepository überlassen, zu wissen, wie man dies den Anforderungen des Datenbankschemas zuordnen kann.

Innerhalb des Ticketrepositorys können Sie einen Ticketstatus-ID-Cachespeicher für TicketState speichern, der von der Datenbank in eine statische Variable (nur eine Methode) geladen wird. Das Ticket-Repository würde den Ticket.State-Wert IDs aus diesem Cache für Einfügungen / Aktualisierungen zuordnen.

%Vor%     
G-Wiz 10.02.2010 23:56
quelle