18

Martin Fowler betrachtet Anemic Domain Model als ein Anti-Pattern.Rich Domain Model und ORM

Auch das Rollen des Persistenzmodells als Domänenmodell scheint aufgrund von Object Relational Impedence Missmatch schwerwiegend zu sein. Für Beharrlichkeit und Normalisierung sakes neigen wir dazu, Klassen in sehr kleine kleine Stücke zu zerlegen, Slapping-Methoden auf diese Klassen ist albern. Plus-Persistenz ändert sich selten, aber Geschäftslogik ändert sich ein gutes Stück.

Also brauchen wir ein DomainModel, das auf dem Persistenzmodell aufbaut (anstatt ein und dasselbe zu sein). Dieses Domänenmodell enthält dann Geschäftslogikeigenschaften und -methoden.

Aber jetzt sind diese Domain-Modelle immer noch hinter dem Service, und um sie nach außen offen zu legen, müssen wir sie zu DTOs konvertieren.

Wir machen so mannigmappings hier.

  1. Persistenz zu Domain Model
  2. Um Domain Model in DTOs konvertiert entlang zwischen den Diensten passieren

Es endet hier nicht, da der DTO muß in das Ansichtsmodell abgebildet werden.

All dies und das Problem der Duplizierung der Validierungslogik geht immer noch nicht weg, weil der Client eine Echtzeitvalidierung wünscht. ViewModel weiß nichts über die Validierung. In einem SPA müssen Sie beispielsweise die Validierungslogik auf der Clientseite (normalerweise in JavaScript) erneut schreiben.

Auch Dienste sind von Natur aus zustandslos (Nachricht oder RPC-orientiert), also machen wir all diese Kartierung, zwischen Persistence, zu OO dann zurück zu Procedural, zu welchem ​​Nutzen? Wie würden Sie die Kosten für die meisten IT-Budgets praktisch rechtfertigen?

Ich bekomme, wie vollständige DDD, mit Aggregatwurzeln, Domain-Modelle usw. wäre "cool" aber wie können Sie die Kosten und die Auswirkungen auf dev Produktivität rechtfertigen?

Antipattern (oder Antipattern) ist ein Muster, in geschäftlichen oder privaten verwendet Operationen oder Software-Engineering, die häufig verwendet werden, jedoch ist unwirksam und/oder kontraproduktiv in der Praxis

Und wenn ja , würden DDD und Rich Domain Model nicht in die Anti-Pattern-Definition über dem "Lean" Domain Model passen. Entschuldigung, ich verachte das geladene Wort "Anemic".

Indem Sie das Domänenmodell "Lean" beibehalten, erlauben Sie es tatsächlich, ohne das "abstrakte Abhängigkeitsprinzip", "sich nicht selbst zu wiederholen" und den zeitraubenden, langwierigen und fehleranfälligen Prozess der Zuordnung einer Daten zu teilen Träger zu einem anderen, und was auch immer verbundenen Unit Test, der darüber hinaus geht (es sei denn, Sie denken, Mapping ohne Unit Testing zu tun und hoffen auf das Beste).

Antwort

7

Es sieht so aus, als würden Sie viele Konzepte vermischen, indem Sie den reichen Domänenmodellansatz für Dinge verantwortlich machen, für die er nicht direkt verantwortlich ist.

  • Rich-Domain-Modell ist orthogonal zur Schichtarchitektur, vor allem ein reiches Domänenmodell mit nicht die Anzahl der Schichten diktieren Sie haben, welche Datenstrukturen sollten sollten abgebildet werden zwischen diesen Schichten und wie sie ausgetauscht werden.

  • Das Rich-Domain-Modell ist orthogonal zur Validierung und sagt nichts über die Notwendigkeit einer clientseitigen Überprüfung zusätzlich zur Back-End-Validierung aus.

Mit anderen Worten, anämisch Ihre Domain-Modell machen mit allen Business-Logik in Dienste werden nicht unbedingt Sie sparen eine Menge Text DTO Mapping-Code zu schreiben, noch wird es die Notwendigkeit für die Client-Seite „double entfernen Überprüfung "(was übrigens eine allgemein akzeptierte Best Practice ist).

Dies bedeutet nicht, dass Ihr Punkt über die Kosten und das Gewicht einer vollwertigen mehrschichtigen Architektur nicht gültig ist. Vielleicht finden Sie Interesse an diesem Beitrag von Mark Seemann über ähnliche Bedenken zu diskutieren: http://blog.ploeh.dk/2012/02/09/IsLayeringWorthTheMapping.aspx

+0

Ich denke, der Artikel, den Sie verlinkt haben, fasst das Dilemma zusammen. Abgesehen davon, dass ich nicht daran glaube, Domain Model durch die Leitung zu schicken, scheint das die Aufgabe eines DTO zu sein. Es macht keinen Sinn, Verhalten auf dem DTO zu haben und dies dem Kunden offen zu legen. Für mich ist die Architektur also nur "machbar" mit einer weiteren Ebene der Abstraktion und Kartierung zusätzlich zu den 3, die er erwähnt hat. Und das ist eine Menge Mapping! Zu sagen, dass die andere Möglichkeit der Einführung von UI-Bedenken in die Domäne aus Gründen der Wiederverwendung nicht richtig ist, ist auch richtig. Ich denke, es gibt ein "glücklicheres" Medium zwischen den beiden extremen Pollern. – Alwyn

+0

"Bewegen Sie weniger Daten herum und die Dinge werden wahrscheinlich einfacher" - Seine eigene Schlussfolgerung am Ende des Artikels, die für mich wie Lean Model klingt. – Alwyn

+0

"Es macht keinen Sinn, Verhalten auf dem DTO zu haben und dies dem Client offen zu legen." Jetzt verstehe ich die Verbindung, die Sie zwischen Rich/Anemic Domain Model und Layering herstellen. Implizieren Sie, dass Domänenobjekte von so viel Geschäftslogik wie möglich entfernt werden sollten, um sie direkt an die UI-Ebene zu senden, ohne DTOs zu benötigen? Oder ist es etwas anderes, das du als "Lean Model" bezeichnest? – guillaume31

2

Zunächst einmal glaube ich nicht, dass Sie wirklich leicht von der Duplizierung der Validierungslogik auf dem Client und auf dem Server entkommen können. Dies ist jedoch nicht auf DDD beschränkt. Es gibt einige Mechanismen, um den Schmerz zu lindern, aber einige Anstrengungen werden immer erforderlich sein.

Der andere Teil ist diese ganze Abbildung von Geschäfts :)

Was Sie tun, liest auszuführen effektiv verwendet. Sie denken vielleicht, dass Sie Ihre Entität lesen müssen, um sie zu bearbeiten. Dies ist der Fall, wenn Sie auf Entitätsbasis (Entität wahrscheinlich mehr in DB-Begriffen - Ganzer Datensatz) Operationen ausführen als auf aufgabenbasierten Operationen für Ihr Entitätsobjekt. Ein albernes Beispiel kann sein, dass ein Kunde sich an das Call-Center anmeldet eine Adresse ändern. Der Operator ruft den Kundendatensatz auf und bearbeitet die Adresse. Dies ist Entity-basiert und führt zu typischen Problemen w.r.t. Parallelität, da 2 Aktionen für denselben Datensatz ausgeführt werden können (jedoch unwahrscheinlich). Dies ist ein sehr traditioneller Ansatz für das UX-Design: "Bearbeiten Sie den Datensatz".

Vergleichen Sie dies mit einer Schaltfläche auf dem Bildschirm, die besagt: "ändern Sie eine Adresse". Sie ändern nur die Adresse auf der Platte und obwohl das wie das Gleiche scheint, ist es wirklich ganz anders. Die Chancen für 2 Operationen, die die gleiche Adresse ändern, sind eher schmaler als die des gleichen Datensatzes. Bei Bedarf kann die Parallelitätsprüfung für diesen Teil durchgeführt werden.

Nun, wenn man die Domain nicht liest, was würde man lesen. Woher würden die Daten kommen? Hier kommt CQRS (Command/Query Responsibility Segregation) ins Spiel. In der Vergangenheit wurde es mit Event Sourcing verwechselt/kombiniert, aber dies ist nicht erforderlich. Sie können eine einfache Abfrageseite für Ihre Anwendung erstellen, die darauf ausgerichtet ist, die benötigten Daten zurückzugeben. In C# verwendete ich eine DataRow, wenn es eine einzelne Instanz ist, eine DataTable für mehrere Instanzen und eine benutzerdefinierte DTO für etwas komplexer. Es kann einen Weg geben, wie man mit anonymen Typen davonkommt (habe das noch nicht untersucht).

Deshalb:

Domain Model = Operationen/Berechnung/Schreib Abfragedienste = lesen

Es gibt Situation, wo Sie weg, da es mit einfach Laden ein Unternehmen/Aggregate wie in einer Web-Anwendung bekommen ist sich Ihres Domänenmodells bewusst (oder vielleicht bewusst), aber ein intelligenter Client wäre ein bisschen ein Anti-Pattern.

Die Begründung ist ziemlich schwierig, aber es läuft auf Wartung hinaus. Wenn Ihre Herangehensweise die Wartungslast nicht verringert, dann ist die Wahrscheinlichkeit groß, dass etwas nicht korrekt angewendet wird und ein gewisses Refactoring erforderlich ist.

Bei DDD geht es nicht nur um die technische Implementierung, obwohl dies einen langen Weg in Richtung der richtigen OO-Modellierung bedeutet. Ich denke, dass die anderen Ideen sowieso in die Software einfließen, so dass die Software ohnehin im Vordergrund steht. Wir alle wollen sehen, wo der Gummi auf die Straße trifft.

Wie die meisten Dinge kann DDD falsch :)

4

tl erfolgen; dr Das Domain-Modell definiert ist nicht gut, es ist wahrscheinlich mit einem db zentrierten Ansatz im Auge behalten.

Die Hauptziele von DDD ist es, die Business-Konzepte und Prozesse in Code zu modellieren. Ich bezweifle wirklich, dass Ihre Geschäftskonzepte und Prozesse nur Taschen von Eigenschaften sind. Aber wenn sie wirklich dann ja sind, kann das Domänenmodell dasselbe wie das Persistenzmodell sein, so dass Sie keine Zuordnung vornehmen müssen.

Das Persistenzmodell modelliert, wie Objektstatus gespeichert wird. Wenn Sie sich nicht in der Domäne von Datenbanken befinden, können Domänen- und Persistenzmodell nicht denselben Zweck erfüllen.Einer der größten Fehler, die ich bei DDD sehe, ist, über das Domänenmodell nachzudenken, als wäre es noch datengesteuert. In DDD haben Sie keine konkrete Datenbank. Sie haben Repositories. Es gibt keine Eins-zu-Viele-, Viele-Zu-Viele- usw. Beziehungen. Es gibt keine Tabellen und keine Zeilen. Es gibt nur Objekte, die versuchen, die Domain so genau wie möglich darzustellen.

Einfach gesagt, kümmert sich die Domäne um die Modellierung des Geschäftsverhaltens, während die Persistenz sich darum kümmert, den Objektstatus zu speichern. Ich sehe hier zwei verschiedene Verantwortlichkeiten.

Über Validierung, haben Sie 2 Arten: Validierung von Eingabedaten Format und dann die Validierung von anderen Geschäftsregeln nach dem, was Sie in einem Objektzustand ändern.

Über die Vervielfältigung, ich denke, Sie beziehen sich auf das Eingabeformat, aber wie @EbenRoux sagte, es gibt Mechanismus, der dabei helfen kann. In asp.net mvc haben die meisten dieser Validierungsregeln auch die js-Version.

Lassen Sie mich Ihnen ein kleines Geheimnis mit Dienstleistungen erzählen. Während ihre Schnittstelle in der Domäne definiert werden kann, kann ihre Implementierung in der Persistence-Schicht sitzen, so dass sie direkt mit dem Speicher arbeiten können. Und da der Rest der App den Dienst in seiner abstrakten Form (die Schnittstelle) verwendet, wird nur der DI-Container das schmutzige Geheimnis kennen.

Bei DDD geht es nicht darum, cool zu sein, sondern darum, eine Anwendung entsprechend der Domäne zu entwickeln. Ich wette, nur wenige entwickeln eine App für den einzigen Zweck, eine Benutzeroberfläche für die db zu sein. Die Mehrheit zielt darauf ab, mit ihrer Software einen Service anzubieten, um ein virtuelles Produkt zu bauen, das ein Problem löst. Es macht Sinn, dass das Design der App das zu lösende Problem löst und nicht durch die technischen Tools, die Sie gerade verwenden.

Wie klingt das, Sie wollen ein Ziegelhaus, aber der Konstrukteur sagt: "Tut mir leid, aber meine Säge funktioniert nur mit Holz". Nun, benutze keine Säge, benutze ein anderes Werkzeug, das helfen kann, einen Ziegelstein zu schneiden. Die Werkzeuge müssen an das Problem angepasst werden, nicht umgekehrt.

+0

Also ist die Domain in der DDD Stateful oder Staatenlos? Sollte die Domain dann ihre Eigenschaften freilegen? Wenn nicht, was wären die Parameter und Rückgabetypen der Domänenmethoden ?, DTOs? Wenn es seine Eigenschaften freilegt, wie ist das besser als das anämische Modell? – Alwyn

+0

Domain ist in erster Linie über das Verhalten.Natürlich kann ein Domain-Objekt Eigenschaften haben, aber es hat nicht nur Eigenschaften. Und diese Eigenschaften sind nicht nur Primitive. Wie speichern Sie IFormattedContent direkt in einer Spalte? Ich fange an zu denken, dass Ihre aktuelle Domäne nur eine Sammlung von datengesteuertem prozeduralem Code ist, der nur DDD-Begriffe verwendet. – MikeSW

+0

@Alwyn Teil der Domäne ist Stateful - es ist genau der Punkt der Entitäten, einen Zustand sowie eine Identität zu haben, so dass wir Änderungen in diesem Zustand verfolgen können. Wertobjekte dagegen sind nicht zustandsbehaftet (wenn möglich, im Status "eingefroren"). Domain-Dienste sollten eindeutig staatenlos sein. – guillaume31

Verwandte Themen