2009-02-09 12 views
25

Ich habe angefangen, über DDD zu lernen und wollte wissen, wie andere ihre Projekte organisiert haben.Wie man ein Domain Driven Design Project organisiert?

Ich habe durch die Organisation um meine AggregateRoots begann:

MyApp.Domain (Namespace für Domain-Modell)

MyApp.Domain.Product
- Produkt
- IProductService
- IProductRepository
- usw.

MyApp.Domain.Comment
- Kommentar
- ICommentService
- ICommentRepository
- etc

MyApp.Infrastructure
- ...

MyApp.Repositories
- ProductRepository: IProductRepository
- usw.

Das Problem, das ich damit konfrontiert bin, ist, dass ich mein Domain-Produkt als MyApp.Domain.Product.Product oder Product.Product verweisen muss. Ich bekomme auch einen Konflikt mit meinem linq Datenmodell für Produkt .... Ich muss hässliche Codezeilen verwenden, um zwischen den zwei wie MyApp.Domain.Product.Product und MyApp.Respositories.Product zu unterscheiden.

Ich bin wirklich daran interessiert zu sehen, wie andere ihre Lösungen für DDD organisiert haben ...

ich Visual Studio als mein IDE verwende.

Vielen Dank.

Antwort

19

Ich versuche, Dinge zu halten, sehr einfach, wann immer ich kann, so in der Regel so etwas wie dies funktioniert für mich:

Myapp.Domain - Alle domänenspezifische Klassen teilen diesen Namespace

Myapp.Data - dünne Schicht, die abstrahiert die Datenbank von der Domäne.

Myapp.Application - All "Support-Code", Protokollierung, gemeinsamer Dienstprogramm Code, Service Verbraucher usw.

Myapp.Web - Der Web-UI

So werden Klassen können 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.

Die Idee, die ich versuche, im Auge zu behalten, wie ich entlang gehen, ist, dass die „Domäne“ Namespace ist das, was die eigentliche Logik der Anwendung erfaßt. Also, was geht dort ist, was Sie mit den "Domain-Experten" (Die Jungs, die die Anwendung verwenden wird) darüber sprechen. Wenn ich etwas schreibe, weil es etwas erwähnt hat, sollte es im Domain-Namespace sein, und wenn ich etwas schreibe, das sie nicht erwähnt haben (wie Logging, Tracing-Fehler usw.), sollte es NICHT im Domain-Namespace sein.

Aus diesem Grund bin ich auch vorsichtig, zu komplizierte Objekthierarchien zu machen. Im Idealfall sollte eine etwas vereinfachte Zeichnung des Domänenmodells für Nicht-Programmierer intuitiv verständlich sein.

Zu diesem Zweck fange ich normalerweise nicht an, indem ich über Muster im Detail nachdenke. Ich versuche, die Domäne so einfach wie möglich zu modellieren, indem ich nur den objektorientierten Designrichtlinien folge. Was muss ein Objekt sein? Wie hängen sie zusammen?

DDD beschäftigt sich mit der Handhabung komplexer Software, aber wenn Ihre Software selbst nicht sehr komplex ist, könnten Sie leicht in eine Situation geraten, in der DDD Komplexität hinzufügt, anstatt sie zu entfernen.

Sobald Sie haben ein gewisses Maß an Komplexität in Ihrem Modell beginnen Sie zu sehen, wie bestimmte Dinge sollen, organisiert werden und dann werden Sie wissen, welche Muster zu bedienen, welche Klassen Aggregate usw.

In meinem Beispiel , Myapp.Domain.Sales.Order wäre ein aggregierter Root in dem Sinne, dass wenn er instanziiert ist, er wahrscheinlich andere Objekte enthält, wie beispielsweise ein Kundenobjekt und eine Sammlung von Auftragspositionen, und Sie nur auf die Auftragspositionen für diesen bestimmten Bereich zugreifen würden Bestellung über das Bestellobjekt.

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, so dass die Befehlsklasse selbst Werte und Eigenschaften hat, die in der Anwendung nützlich sind.

Also werde ich Referenz 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.

+0

Das macht Sinn ... Auftrag und Kunde sind Sie AggRoots richtig? Wenn Sie also auf Ihr Order-Objekt verweisen, müssen Sie es wie folgt tun: Myapp.Domain.Sales.Order.Order ?? –

+0

Ja und nein - ich habe mein Beispiel etwas erweitert, da der Kommentarbereich etwas zu kurz ist. – Console

+0

'Manager' Klassen in' Data' Namespace machen mich zum anämischen Modell –

0

Ihre Domain hat wahrscheinlich einen Namen, daher sollten Sie diesen Namen als Namespace verwenden.

I usally Repository Implementierung und den Datenzugriff setzen Details in einem Namespace Persistance unter der Domain Namespace genannt. Die Anwendung verwendet ihren eigenen Namen als Namespace.

5

Ich mag die Domäne im Stammnamespace der Anwendung, die in ihrem eigenen Montag:

Acme.Core.dll [Stammnamespace: Acme]

Dies stellt ordentlich die Tatsache, dass die Domain in Umfang von allen ist andere Teile der Anwendung. (Für mehr, siehe The Onion Architecture von Jeffrey Palermo).

Als nächstes habe ich eine Datenbestückung (in der Regel mit NHibernate), die die Domain-Objekte auf die Datenbank abbildet. Diese Schicht implementiert Repository und Service-Schnittstellen:

Acme.Data.dll [Stammnamespace: Acme.Data]

Dann habe ich eine Präsentationsanordnung Elemente meiner UI-Muster-of-Wahl erklärt:

Acme.Presentation.dll [Stammnamespace : Acme.Presentation]

Schließlich gibt es das UI-Projekt (unter der Annahme einer Web-App hier). Dies ist, wo die Zusammensetzung der Elemente in den vorhergehenden Schichten erfolgt:

Acme.Web [Stammnamespace: Acme.Web]

0

würde ich auschecken codecampserver seit dem Setup es durchaus üblich ist.

Sie haben ein Kernprojekt, in dem sie sowohl die Anwendungs- als auch die Domänenebene enthalten. I.e. das Innere der Zwiebel (http://jeffreypalermo.com/blog/the-onion-architecture-part-1/).

Ich mag es eigentlich, den Kern in separate Projekte zu zerlegen, um die Richtung der Abhängigkeit zu steuern. So typisch ich habe:

MyNamespace.SomethingWeb < - mehrere UIs
MyNamespace.ExtranetWeb < - mehrere UIs

MyNamespace.Application < - Evans' Anwendungsschicht mit Klassen wie Customer
MyNamespace.Domain

  • MyNamespace.Domain.Model < - Einheiten
  • MyNamespace.Dom ain.Services < - doman Dienste
  • MyNamespace.Domain.Repositories

MyNamespace.Infrastructure < - Repo-Implementierung usw.

MyNamespace.Common < - Ein Projekt, das alle anderen Projekten eine haben Abhängigkeit, die Dinge wie ein Logger, Util-Klassen, etc. hat

3

Obwohl Sie auch ein. NET-Entwickler sind, ist die Java implementation reference of the cargo app von DDD von Eric Evans und Citerus eine gute Ressource.

Im Dok-Code können Sie die DDD-Organisation in begrenzten Kontexten und Aggregaten in Aktion sehen, direkt in den Java-Paketen.

Darüber hinaus könnten Sie Billy McCafferty Sharp Architecture betrachten. Es ist eine ASP.Net MVC-, NHibernate/Fluent NHibernate-Implementierung, die mit DDD erstellt wurde.

Zugegeben, Sie müssen noch eine Ordner/Namespace-Lösung anwenden, um die Kontexte bereitzustellen. Aber, koppeln Sie den Evans-Ansatz mit #Arch und Sie sollten auf Ihrem Weg sein.

Lassen Sie uns wissen, was Sie vorhaben. Ich bin auf dem gleichen Weg und nicht weit von dir!

Glücklich Codierung,

Kurt Johnson

+0

UPDATE: Ich sollte hinzufügen, dass die Who-Can-Hilfe-Me (WCHM) Gabel von Sharp Architecture. Ab September 2010 wurden die WCHM-Betreuer in das Mitarbeiterteam für Sharp aufgenommen. WCHM reorganisiert das Sharp Visual Studio-Projekt in Solution-Ordner, die sich explizit auf DDD-Konzepte beziehen. Es gibt Ordner für Domäne (domänen- und domänenspezifische Infrastruktur), Präsentation (Web-Ansichten und Web-Controller), Framework (Code, der über Domänen hinweg wiederverwendbar ist, und eine Services-Ebene (Aufgaben). Zukünftige Versionen von Sharp Architecture sollen diesen Ansatz widerspiegeln . –

Verwandte Themen