33 Stimmen

Wie organisiert man ein Domain Driven Design Projekt?

Ich habe angefangen, mich mit DDD zu beschäftigen und wollte wissen, wie andere ihre Projekte organisiert haben.

Ich habe damit begonnen, meine AggregateRoots zu organisieren:

MyApp.Domain (Namespace für das Domänenmodell)

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

MyApp.Domain.Kommentar
- Kommentar
- ICommentarDienst
- ICommentar-Repository
- usw.

MeineApp.Infrastruktur
- ...

MyApp.Repositories
- ProductRepository : IProductRepository
- usw.

Das Problem, das ich in mit diesem gestoßen ist, dass ich meine Domäne Produkt als MyApp.Domain.Product.Product oder Product.Product verweisen müssen. Ich bekomme auch einen Konflikt mit meinem Linq-Datenmodell für Produkt....Ich muss hässliche Codezeilen verwenden, um zwischen den beiden wie MyApp.Domain.Product.Product und MyApp.Respoitories.Product zu unterscheiden.

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

Ich verwende Visual Studio als meine IDE.

Vielen Dank.

23voto

Console Punkte 981

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.

0 Stimmen

Ergibt Sinn...Order und Customer sind Sie AggRoots richtig? Wenn Sie also Ihr Order-Objekt referenzieren, müssen Sie es so machen: Myapp.Domain.Sales.Order.Order?

0 Stimmen

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

0 Stimmen

Manager Klassen in Data Der Namensraum erinnert mich an ein blutarmes Modell

5voto

Bryan Watts Punkte 43539

Ich mag es, wenn die Domäne im Root-Namensraum der Anwendung, in einer eigenen Assembly, liegt:

Acme.Core.dll [Root-Namespace: Acme ]

Damit wird deutlich, dass die Domäne in den Anwendungsbereich aller anderen Teile der Anwendung fällt. (Für weitere Informationen, siehe Die Architektur der Zwiebel von Jeffrey Palermo).

Als nächstes habe ich eine Datenzusammenstellung (normalerweise mit NHibernate ), die die Domänenobjekte in der Datenbank abbildet. Diese Schicht implementiert Repository- und Service-Schnittstellen:

Acme.Data.dll [Root-Namespace: Acme.Data ]

Dann habe ich eine Präsentationsbaugruppe, die Elemente des von mir gewählten UI-Musters deklariert:

Acme.Presentation.dll [Root-Namespace: Acme.Presentation ]

Schließlich gibt es noch das UI-Projekt (hier wird von einer Webanwendung ausgegangen). Hier findet die Zusammensetzung der Elemente in den vorangegangenen Schichten statt:

Acme.Web [Root-Namespace: Acme.Web ]

3voto

Kurt Johnson Punkte 413

Obwohl Sie auch ein .Net-Entwickler sind, ist die Java-Implementierungsreferenz der Cargo-App von DDD von Eric Evans und Citerus ist eine gute Quelle.

Im dokumentierten 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's Scharfe Architektur . Es ist eine ASP.Net MVC, NHibernate/Fluent NHibernate-Implementierung, die mit DDD im Auge gebaut wird.

Allerdings müssen Sie immer noch eine Ordner-/Namensraumlösung anwenden, um die Kontexte bereitzustellen. Aber wenn Sie den Evans-Ansatz mit #Arch kombinieren, sollten Sie auf einem guten Weg sein.

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

Viel Spaß beim Kodieren,

Kurt Johnson

0 Stimmen

UPDATE: Ich sollte hinzufügen, dass der Who-Can-Help-Me (WCHM) Fork von Sharp Architecture. Seit September 2010 sind die WCHM-Maintainer in das Contributor-Team für Sharp aufgenommen worden. WCHM reorganisiert das Sharp Visual Studio Projekt in Solution-Ordner, die sich explizit auf DDD-Konzepte beziehen. Es gibt Ordner für die Domäne (Domäne und domänenspezifische Infrastruktur), die Präsentation (Webansichten und Webcontroller), das Framework (Code, der als domänenübergreifend wiederverwendbar angesehen wird) und eine Dienstebene (Tasks). Künftige Versionen von Sharp Architecture werden diesen Ansatz voraussichtlich widerspiegeln.

1voto

thinkbeforecoding Punkte 6520

Ihre Domain hat wahrscheinlich eine Namen, also sollten Sie diesen Namen als Namespace verwenden.

Ich setze normalerweise Repository Implementierung und Datenzugriff Details in einem Namensraum namens Persistance unter dem Domain Namespace.

Die Anwendung verwendet ihren eigenen Namen als Namespace.

0voto

pondermatic Punkte 6235

Ich würde mal bei codecampserver nachsehen, da die Einrichtung dort recht verbreitet ist.

Sie haben ein Kernprojekt, in das sie sowohl die Anwendungs- als auch die Domänenschicht einbeziehen. D.h. die Innenseite der Zwiebel ( http://jeffreypalermo.com/blog/the-onion-architecture-part-1/ ).

Ich mag es eigentlich, den Kern in separate Projekte aufzuteilen, um die Richtung der Abhängigkeit zu kontrollieren. Also typischerweise habe ich:

MyNamespace.SomethingWeb <-- mehrere Benutzeroberflächen
MyNamespace.ExtranetWeb <-- mehrere Benutzeroberflächen

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

  • MyNamespace.Domain.Model <-- Entitäten
  • MyNamespace.Domain.Services <-- doman services
  • MyNamespace.Domain.Repositories

MyNamespace.Infrastructure <-- Repo-Implementierung usw.

MyNamespace.Common <-- Ein Projekt, von dem alle anderen Projekte abhängig sind und das Dinge wie einen Logger, Util-Klassen usw. enthält.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X