Ich versuche, die Dinge so einfach wie möglich zu halten, also funktioniert so etwas für mich normalerweise:
Myapp.Domain - Alle domänenspezifischen Klassen teilen sich diesen Namespace
Myapp.Data - Dünne Schicht, die die Datenbank von der Domäne abstrahiert.
Myapp.Application - Sämtlicher "Unterstützungscode", Protokollierung, gemeinsamer Dienstprogrammcode, Dienstverbraucher usw.
Myapp.Web - Die Web-UI
So werden die Klassen zum Beispiel sein:
- Myapp.Domain.Sales.Order
- Myapp.Domain.Sales.Customer
- Myapp.Domain.Pricelist
- Myapp.Data.OrderManager
- Myapp.Data.CustomerManager
- Myapp.Application.Utils
- Myapp.Application.CacheTools
Etc.
Der Gedanke, den ich im Hinterkopf zu behalten versuche, ist, dass der "Domain"-Namensraum die eigentliche Logik der Anwendung enthält. Was also dort hinkommt, ist das, worüber man mit den "Domänenexperten" (den Leuten, die die Anwendung benutzen werden) sprechen kann. Wenn ich etwas wegen etwas kodiere, das sie erwähnt haben, sollte es im Domain-Namensraum liegen, und wenn ich etwas kodiere, das sie nicht erwähnt haben (wie Protokollierung, Fehlerverfolgung usw.), sollte es NICHT im Domain-Namensraum liegen.
Aus diesem Grund bin ich auch vorsichtig, wenn es darum geht, zu komplizierte Objekthierarchien zu erstellen. Idealerweise sollte eine etwas vereinfachte Zeichnung des Domänenmodells auch für Nicht-Programmierer intuitiv verständlich sein.
Aus diesem Grund mache ich mir normalerweise keine allzu detaillierten Gedanken über Muster. Ich versuche, die Domäne so einfach wie möglich zu modellieren und folge dabei einfach den Standardrichtlinien für objektorientiertes Design. Was muss ein Objekt sein? Wie sind sie miteinander verbunden?
Bei DDD geht es meiner Meinung nach um den Umgang mit komplexer Software, aber wenn Ihre Software an sich nicht sehr komplex ist, könnten Sie leicht in eine Situation geraten, in der die DDD-Methode die Komplexität eher erhöht als sie zu beseitigen.
Sobald Sie ein gewisses Maß an Komplexität in Ihrem Modell erreicht haben, werden Sie erkennen, wie bestimmte Dinge organisiert werden sollten, und Sie werden wissen, welche Muster Sie verwenden sollten, welche Klassen Aggregate sind usw.
In meinem Beispiel wäre Myapp.Domain.Sales.Order ein aggregierter Root in dem Sinne, dass er, wenn er instanziert wird, wahrscheinlich andere Objekte enthält, wie z. B. ein Kundenobjekt und eine Sammlung von Auftragszeilen, und Sie würden nur auf die Auftragszeilen für diesen bestimmten Auftrag über das Auftragsobjekt zugreifen.
Um die Dinge jedoch einfach zu halten, würde ich kein "Master"-Objekt haben, das nur alles andere enthält und keinen anderen Zweck hat. Die Auftragsklasse wird also selbst Werte und Eigenschaften haben, die in der Anwendung nützlich sind.
Ich werde also auf Dinge wie:
Myapp.Domain.Sales.Order.TotalCost
Myapp.Domain.Sales.Order.OrderDate
Myapp.Domain.Sales.Order.Customer.PreferredInvoiceMethod
Myapp.Domain.Sales.Order.Customer.Address.Zip
usw.