DDD mit ORM Wohin soll die Geschäftslogik gehen?

10

Ich habe in der Vergangenheit ein MDA-Tool (Model Driven Architecture) verwendet, mit dem wir über UML modelliert haben. Dadurch wurden unter anderem die Geschäftseinheiten (unser Domänenmodell) und das ORM (Mapping usw.) generiert.

Ein Großteil des Geschäftscodes und der Dienste, die in der Domäne arbeiten, waren Teil des Modells, und unsere Repositorys gaben die Geschäftsentitäten zurück (es wäre also unmöglich gewesen, zu einem anderen ORM zu wechseln (nicht das, was wir wollten)).

Jetzt starte ich jedoch ein Projekt und möchte in DDD denken.

Bisher fühlt es sich so an, als würde ich meine Geschäftslogik in mein Domain-Modell einfügen und über Repositories mit dem ORM arbeiten (was auch immer ich gewählt habe). Wenn ich jedoch weiterhin das MDA-Tool für den ORM-Teil der Anwendung verwenden möchte, wäre das hier erstellte Modell sehr anämisch (dh es enthält keine Geschäftslogik). In ähnlicher Weise wäre es auch ein anämisches Modell, wenn ich Entity Framework (.net) oder NHibernate für mein ORM verwenden würde. Ich bin mir nicht sicher, wo Sie die Geschäftslogik platzieren würden, wenn ich nur NHibernate verwenden würde.

Bin ich richtig, wenn ich so denke, mit anderen Worten, mit DDD die gesamte Geschäftslogik in der Domäne und verwende das ORM nur für die Persistenz über Repositorys?

JD01
quelle

Antworten:

12

Es wäre also unmöglich gewesen, zu einem anderen ORM zu wechseln (nicht das, was wir wollten).

Das scheint falsch. Ein Hauptvorteil des Repository-Musters besteht darin, dass Sie die Datenzugriffslogik ausblenden und sie leicht austauschbar ist.

Bisher fühlt es sich so an, als würde ich meine Geschäftslogik in mein Domain-Modell einfügen und über Repositories mit dem ORM arbeiten (was auch immer ich gewählt habe). Wenn ich jedoch weiterhin das MDA-Tool für den ORM-Teil der Anwendung verwenden möchte, wäre das hier erstellte Modell sehr anämisch (dh es enthält keine Geschäftslogik). In ähnlicher Weise wäre es auch ein anämisches Modell, wenn ich Entity Framework (.net) oder NHibernate für mein ORM verwenden würde. Ich bin mir nicht sicher, wo Sie die Geschäftslogik platzieren würden, wenn ich nur NHibernate verwenden würde.

Ein anämisches Domänenmodell wird von vielen als schlechte Praxis angesehen, beispielsweise von Martin Fowler. Sie sollten ein solches Design vermeiden, da ein solches Modell eher zu prozeduralen Designtechniken als zu einem guten objektorientierten Design führt. Sie haben dann Datenklassen und Manager- / Verarbeitungsklassen, was bedeutet, dass Sie Status und Verhalten getrennt haben. Aber ein Objekt sollte wirklich "Zustand und Verhalten" sein.

NHibernate leistet hervorragende Arbeit bei der Unwissenheit über Beharrlichkeit. Sie können die Zuordnungsdetails in XML oder mit FluentNHibernate ausblenden und einfach einfache POCOs schreiben. Mit NHibernate ist es sehr einfach, ein umfangreiches Domain-Modell zu erstellen. Ich denke, Sie können dies auch mit dem Entity Framework und dem MDA-Tool tun. Solange dieses Tool Teilklassen erzeugt, können Sie den generierten Code ziemlich einfach erweitern, ohne befürchten zu müssen, dass eine neue Generation Ihren vom Benutzer geschriebenen Code zerstören könnte.

Um diese lange Geschichte kurz zu machen. Wenn Sie NHibernate verwenden, hindert Sie nichts, ich wiederhole nichts daran , ein reichhaltiges Domain-Modell anzunehmen . Ich empfehle die Verwendung mit FluentNHibernate und die Zuordnung von Hand. Das Schreiben des Mapping-Codes dauert nur 5 bis 10 Minuten. Ich nehme an, dass das Gleiche für das Entity-Framework gilt und dass seine Tools zumindest Teilklassen erstellen, die leicht erweiterbar sind.

Bin ich richtig, wenn ich so denke, mit anderen Worten, mit DDD die gesamte Geschäftslogik in der Domäne und verwende das ORM nur für die Persistenz über Repositorys?

Zum größten Teil sind Sie richtig. Sie sollten ein reichhaltiges Domain-Modell haben. Besonders wenn die Dinge immer komplexer werden, ist es einfacher, sie zu warten und zu erweitern, wenn Sie sie richtig entworfen haben. Beachten Sie jedoch, dass DDD auch die Dienste (Domänenschicht und Anwendungsschicht) zur Implementierung von Geschäftslogik und Fabriken zur Kapselung der Erstellungslogik kennt.

Ich neige auch dazu, Geschäftslogik in Domänenlogik und tatsächliche Anwendungsgeschäftslogik zu unterscheiden. Die Domänenlogik gibt an, wie die Domäne interagiert und sich verhält, während die Anwendungslogik, bei der es sich um eine völlig andere Schicht handelt, die Verwendung der Domäne für den jeweiligen Anwendungsfall / die jeweilige Anwendung kapselt. Oft muss ich das Domänenmodell aktualisieren, um bestimmte Anwendungsfälle zu unterstützen und es leistungsfähiger zu machen.

Falke
quelle
2
+1: Ich trenne auch die Domänenlogikschicht von der Anwendungslogikschicht. Ich habe das gesamte ORM- und Datenbankmaterial in die Domänenlogikschicht eingefügt. Die Anwendungslogikschicht weiß nichts über ORM, Transaktionen und all diese Dinge: Sie sieht nur Geschäftslogikklassen und ruft deren Methoden auf. Ich finde diesen Ansatz sehr effektiv, um eine einfachere und sauberere Anwendungslogikschicht zu haben.
Giorgio
@ Falcon: Danke für die Info. Als ich das anämische Modell erwähnte, meinte ich, wenn ich eine Domäne mit DDD erstelle, wäre eine Version meiner Repositorys möglicherweise die mda-Version, bei der ich meine Entitäten nur in die mda-Entitäten (dh anämisches Modell) verschiebe und sie dann beibehalten würde bei Transaktionen usw. Wäre das in Ordnung? Ich bezweifle, dass ich das MDA-Tool verwenden werde, versuche aber nur zu verstehen, wie ich es könnte, wenn ich wollte. Klingt das richtig?
JD01
@ JD01: Ich verstehe Sie nicht ganz, aber es hört sich so an, als ob Sie Domänenmodellentitäten transformieren möchten, damit Sie sie problemlos beibehalten können. Das ähnelt der Verwendung von DTOs, und Automapper (google it) könnte ein nützliches Werkzeug für eine solche Aufgabe sein. Ein solcher Ansatz beeinträchtigt nicht unbedingt die Best Practices von DDD. Schließlich sollen Repositorys auch die Datenzugriffslogik verbergen. Sie könnten einfach Ihre Geschäftsobjekte hinter den Kulissen in MDA-DTOs umwandeln und sie dann beibehalten, und der API-Benutzer würde es nicht einmal bemerken. Ich denke das ist ok
Falcon
1
@ JD01: Ich schlage vor, Sie sehen sich den folgenden Link an, um zu sehen, wie viele Enterprise-Java-Leute das tun. Sie haben grundsätzlich ein DAO, ein DTO und ein BO (Business Object). Für mich sind das zu viele Schichten, aber das Design ist in Ordnung. java.sun.com/blueprints/corej2eepatterns/Patterns/…
Falcon
@ Falcon: Ja, ich dachte, DTOs seien meine MDA-Objekte, nicht dass ich diesen Weg gehen würde. Nur einen Überblick darüber bekommen, was jeder Teil der DDD-Spieler d0. Noch einmal vielen Dank.
JD01
3

Wenn ich jedoch weiterhin das MDA-Tool für den ORM-Teil der Anwendung verwenden möchte, wäre das hier erstellte Modell sehr anämisch (dh es enthält keine Geschäftslogik).

Ich weiß nicht, welches MDA-Tool Sie verwenden, aber diejenigen, mit denen ich gearbeitet habe, erstellen immer Teilklassen, sodass Sie sie mit so viel Geschäftslogik vervollständigen können, wie Sie möchten.

Ich bin jedoch der Meinung, dass MDA-Tools in einem DDD-Kontext etwas weniger geeignet sind als ORMs, da die Codegenerierung häufig dazu führt, dass Klassen anstelle der von uns erwarteten optimierten, klar zum Ausdruck gebrachten Domänenentitäten mit werkzeugspezifischem Rauschen verwechselt werden. Tatsächlich erhalten Sie häufig eine Mischung aus Domänendaten, Persistenzlogik, Einschränkungsvalidierungslogik ... und ich weiß nicht, ob es eine Möglichkeit gibt, diese Probleme mit den meisten MDA-Tools zu trennen.

Und natürlich können Sie den generierten Code nur über Teilklassen berühren, was bedeutet, dass Sie potenzielles Anti-DDD-Verhalten, das integriert werden würde, nicht eliminieren können. Dies ist problematisch bei einem Ansatz, bei dem Sie strenge Barrieren zwischen Aggregaten durchsetzen und die Beziehungen zwischen Ihren Entitäten perfekt anpassen möchten. Die Erstellungszeit in einer Umgebung mit kontinuierlicher Integration kann ebenfalls unter dem zusätzlichen Codegenerierungsschritt leiden.

Abgesehen davon denke ich, dass Falcon so ziemlich alles gesagt hat - absolut nichts in ORM- oder MDA-Tools hindert Sie daran, reichhaltige Domain-Entitäten zu haben.

guillaume31
quelle
Hallo, ich verwende ECO (Enterprise Core Objects) von enabledobjects.com und es ist genau so, wie Sie es beschrieben haben.
JD01
1

Was ich in meinem Team mache, ist, mein Objekt, meine Domäne zu modellieren und gleichzeitig meine Geschäftslogik hinzuzufügen. Ich verwende keine modellgetriebene Entwicklung, die einen Code aus einem Modell generieren würde, bevorzuge jedoch den Annotationsansatz. Ich meine, dass ich auf Objektebene innerhalb des Klassendiagramms ORM-Stereotypen hinzufüge. Dadurch werden Persistenzanmerkungen direkt im Code hinzugefügt, die mit EJB3 / Hibernate kompatibel sind. Die Datenbankerstellung erfolgt im Ruhezustand und schon gar nicht in den UML-Vorlagen. Dies ist viel besser, denn wenn die Codeänderung und die hinzugefügten Anmerkungen nicht genau dem entsprechen, was der Ruhezustandsspezialist tut, kann er sie ändern, aber das Modell ist immer noch gut. Ich kann auch meine Anforderungen ändern und mein Domain-Modell ist noch in Ordnung.

Entwickler können innerhalb jeder Methode Geschäftslogik hinzufügen und einen Kommentar hinzufügen. Ich kann auch Einschränkungen modellieren und hinzufügen. Zum Beispiel sollte der Umsatz über 50.000 liegen, wenn nicht usw. Ich muss ihn nicht codieren, sondern nur in das Modell schreiben, und diese Informationen wären für das Entwicklerteam sichtbar. Wirklich coole und flexible UML.

UML_GURU
quelle