Ich lerne DDD und habe dennoch mehr Fragen als Antworten.
Betrachten wir ein Modell eines Verzeichnisses mit einer enormen Anzahl von Dateien.
So sehe ich das:
Das Verzeichnis ist eine aggregierte Wurzel.
Diese Entität sollte über die Validierungslogik verfügen, die Eindeutigkeit des Dateinamens zu überprüfen, wenn sie hinzugefügt oder nur umbenannt wird. Die Dateientität enthält die Logik 'SetName', mit der Directory über Domain Event über Namensänderungen informiert wird.
Aber wie soll Directory dann funktionieren?
Es ist nicht immer möglich, alle Dateien in den Speicher zu laden. Sollte das Datei-Repository in diesem Fall über eine Ad-hoc-Logik zur Überprüfung der Eindeutigkeit von Namen verfügen? Ich nehme an, es ist eine tragfähige Entscheidung.
Was ist jedoch, wenn einige Dateien bereits mit der aktuellen, noch nicht festgeschriebenen Transaktion hinzugefügt oder umbenannt wurden? (Nichts verbietet dies. Transaktionsgrenzen werden extern in Bezug auf die Geschäftslogik festgelegt.) Wahrscheinlich sollte das Repository sowohl speicherinterne als auch persistierte Zustände berücksichtigen (das Zusammenführen dieser Zustände kann eine nicht triviale Aufgabe sein.)
Wenn also die Gesamtwurzel mit all ihren Kindern in die Erinnerung passt, ist alles in Ordnung. Und sobald Sie nicht alle Entitäten materialisieren können, gibt es Probleme.
Ich würde gerne wissen, wie die Ansätze für solche Situationen aussehen. Vielleicht gibt es überhaupt kein Problem und es liegt nur an meinem Missverständnis des Themas.
quelle
Antworten:
Meine Antwort ist voreingenommen mit Vaughn Vernons großartigem Buch "Implementing Domain Driven Design" (ein Muss)
1. Bevorzugen Sie kleine Aggregate.
Wenn ich Ihre Domain modellieren möchte, würde ich eine
Directory
als Aggregat undFile
als ein anderes Aggregat modellieren .2. Referenzaggregate nach IDs.
Daher
Directory
wird eine Sammlung vonFileId
Wertobjekten haben.3. Verwenden Sie Fabriken, um Aggregate zu erstellen.
Für einen einfachen Fall kann eine Factory-Methode ausreichen
Directory.addFile(FileName fileName)
. Für komplexere Fälle würde ich jedoch eine Domain Factory verwenden.Die Domänenfactory kann
fileName
mithilfe einesFileRepository
und einesUniquefileNameValidator
Infrastrukturdienstes überprüfen, ob dies eindeutig ist .Warum
File
als separates Aggregat modellieren ?Weil
Directories
nicht gemacht sindFiles
. aFile
ist mit einem bestimmten verbundenDirectory
. Stellen Sie sich auch ein Verzeichnis mit Tausenden von Dateien vor. Das Laden all dieser Objekte in den Speicher jedes Mal, wenn ein Verzeichnis abgerufen wird, ist ein Leistungskiller.Modellieren Sie Ihre Aggregate gemäß Ihren Anwendungsfällen. Wenn Sie wissen, dass ein Verzeichnis niemals mehr als 2-3 Dateien enthält, können Sie sie alle als ein einziges Aggregat modellieren. Nach meiner Erfahrung ändern sich die Geschäftsregeln jedoch ständig und es lohnt sich, wenn Ihr Modell flexibel genug war, um die Anforderungen zu erfüllen Änderungen.
Obligatorische Lektüre Effective Aggregate Design von Vaughn Vernon
quelle
inode
Unix-Systemen einfach aus ihrem Verzeichnis referenziert .File
mit einem bestimmten Namen in existierenDirectory
, dh sieDirectory
hat die Invariante: Name Eindeutigkeit. Zumindest ist es wichtig für dieDirectory
, aber nicht für dieFile
. Eigentlich ist @AlexanderLanger richtig: 'Datei' kann von vielen 'Ordnern' referenziert werden. Und der Name ist wahrscheinlich eher Eigentum dieser Referenz als desFile
Selbst. OK. Dann gehört das Umbenennen von Funktionen zuDirectory
, aber auch hier ist es keine gute Idee, Tausende von referenzierten Identitäten zu speichern.bool ContainsFileOfName(int folderId, string fileName)
. Danach kann die Signatur der 'Umbenennen'-Methode wie folgt lauten:void Rename(int fileId, string newName)
In einigenIFolderService
(die das Repository umschließen) wird aufgelöst und gefragt, ob ein solcher Name vorhanden ist.Dies ist per se keine DDD-Frage. Die Hauptfrage hier ist über den Synchronisationskontext (der hier eine aggregierte Wurzel ist).
Zurück zum Thema: Das Verzeichnis soll ein Synchronisationsobjekt mit Dateinamen blockieren und prüfen, ob der angegebene Dateiname zulässig ist, der im schlimmsten Fall O (n) ist.
quelle
Obwohl einige sagen mögen, dass Sie versuchen, Ihr Design zu ändern, besteht immer ein Bedarf, wenn ein AR eine große Liste einfacher Objekte enthält. Und das Speichern im Speicher ist aus Sicht der Leistung nicht das Beste. In solchen Fällen müssen Sie jedoch nur die Transaktionsgrenzen beibehalten. Eine einfache Lösung ist die folgende:
Einige Einschränkungen:
quelle