Ich würde gerne wissen, welche Vor- und Nachteile die Verwendung eines anämischen Domänenmodells hat (siehe Link unten).
Ich würde gerne wissen, welche Vor- und Nachteile die Verwendung eines anämischen Domänenmodells hat (siehe Link unten).
Antworten:
Die Profis:
Die Nachteile:
Warum gibt es so viele Systeme, die dies implementieren, da "Anemic Domain Model" ein Anti-Pattern ist?
Ich denke, es gibt mehrere Gründe
1. Komplexität des Systems
In einem einfachen System (das fast alle Beispiele und Beispielcodes enthält, die Sie im Internet finden) möchte ich Folgendes implementieren:
Produkt zur Bestellung hinzufügen
Ich habe diese Funktion in die Bestellung aufgenommen
public void Order.AddOrderLine(Product product)
{
OrderLines.Add(new OrderLine(product));
}
Schön und super objektorientiert.
Angenommen, ich muss sicherstellen, dass das Produkt im Inventar vorhanden ist, und eine Ausnahme auslösen, wenn dies nicht der Fall ist.
Ich kann es nicht mehr wirklich bestellen, da ich nicht möchte, dass meine Bestellung vom Inventar abhängig ist. Jetzt muss sie in Betrieb genommen werden
public void OrderService.AddOrderLine(Order order, Product product)
{
if (!InventoryService.Has(product)
throw new AddProductException
order.AddOrderLine(product);
}
Ich könnte IInventoryService auch an Order.AddOrderLine übergeben, was eine weitere Option ist, die Order jedoch weiterhin von InventoryService abhängig macht.
In Order.AddOrderLine gibt es noch einige Funktionen, die jedoch normalerweise auf den Bestellbereich beschränkt sind, während meiner Erfahrung nach viel mehr Geschäftslogik außerhalb des Bestellbereichs vorhanden ist.
Wenn das System mehr als nur eine einfache CRUD ist, haben Sie den größten Teil Ihrer Logik in OrderService und nur sehr wenig in Order.
2. Sicht des Entwicklers auf OOP
Im Internet gibt es viele hitzige Diskussionen darüber, welche Logik auf Entitäten angewendet werden soll.
Etwas wie
Order.Save
Sollte Order wissen, wie sie sich selbst retten kann oder nicht? Nehmen wir an, wir haben Repositories dafür.
Kann Order jetzt Bestellpositionen hinzufügen? Wenn ich versuche, es mit einfachem Englisch zu verstehen, macht es auch keinen Sinn. Der Benutzer fügt der Bestellung ein Produkt hinzu. Sollten wir also User.AddOrderLineToOrder () ausführen? Das scheint übertrieben.
Wie wäre es mit OrderService.AddOrderLine (). Jetzt macht es irgendwie Sinn!
Mein Verständnis von OOP ist, dass Sie zur Kapselung Funktionen in Klassen einfügen, in denen die Funktion auf den internen Status der Klasse zugreifen muss. Wenn ich auf die Order.OrderLines-Auflistung zugreifen muss, setze ich Order.AddOrderLine () auf Order. Auf diese Weise wird der interne Status der Klasse nicht angezeigt.
3. IoC-Container
Systeme, die IoC-Container verwenden, sind normalerweise vollständig anämisch.
Dies liegt daran, dass Sie Ihre Dienste / Repositorys mit Schnittstellen testen können, Domänenobjekte jedoch nicht (einfach) testen können, es sei denn, Sie fügen allen Schnittstellen hinzu.
Da "IoC" derzeit als Lösung für alle Ihre Programmierprobleme gelobt wird, folgen viele Leute ihm blind und auf diese Weise erhalten Sie anämische Domänenmodelle.
4. OOP ist schwierig, das Verfahren ist einfach
Ich habe ein bisschen einen " Fluch des Wissens " in diesem Fall, aber ich habe festgestellt, dass es für neuere Entwickler viel einfacher ist, DTOs und Services zu haben als Rich Domain.
Möglicherweise liegt es daran, dass es mit Rich Domain schwieriger ist zu wissen, auf welche Klassen die Logik gesetzt werden soll. Wann werden neue Klassen erstellt? Welche Muster sollen verwendet werden? etc..
Bei zustandslosen Diensten geben Sie es einfach in den Dienst mit dem nächstgelegenen Namen ein.
Danach habe ich schon sehr lange einen Gedanken in meinem Kopf. Ich glaube, dass der Begriff "OOP" eine Bedeutung angenommen hat, die nicht wirklich dafür bestimmt ist. Das Anagramm bedeutet "objektorientierte Programmierung", wie wir alle wissen. Der Fokus liegt natürlich auf dem Wort "orientiert". Es ist nicht "OMP", was "objektprogrammierte Programmierung" bedeutet. Sowohl ADM als auch RDM sind Beispiele für OOP. Sie verwenden Objekte, Eigenschaften, Methodenschnittstellen usw. Es gibt jedoch einen Unterschied zwischen ADM und RDM in der Art und Weise, wie wir Dinge kapseln. Das sind zwei verschiedene Dinge. Zu sagen, dass ADM schlecht ist OOP ist keine genaue Aussage. Vielleicht brauchen wir stattdessen andere Begriffe für verschiedene Kapselungsstufen. Außerdem hat mir der Begriff Anti-Pattern nie gefallen. Es wird normalerweise von Mitgliedern einer gegnerischen Gruppe etwas zugewiesen. Sowohl ADM als auch RDM sind gültige Muster, sie verfolgen einfach unterschiedliche Ziele und sollen unterschiedliche Geschäftsanforderungen lösen. Diejenigen von uns, die DDD praktizieren, sollten dies zumindest zu schätzen wissen und nicht auf das Niveau anderer fallen, indem sie diejenigen verprügeln, die sich für die Implementierung von ADM entscheiden. Nur meine Gedanken.
"Es ist ein Anti-Pattern, daher werden andere Entwickler fragen, ob Sie die Konzepte des objektorientierten Designs verstehen."
"Ein anämisches Domänenmodell ist ein Anti-Muster. Anti-Muster haben keine Vorteile."
Ob das anämische Domänenmodell ein Anti-Muster ist, ist Ansichtssache. Martin Fowler sagt, dass dies der Fall ist. Eine Reihe von Entwicklern, die OO genau kennen, sagen, dass dies nicht der Fall ist. Die Angabe der Meinung als Tatsache ist selten hilfreich.
Und selbst wenn es allgemein als Anti-Muster akzeptiert würde, besteht die Möglichkeit, dass es immer noch einen (wenn auch relativ geringen) Vorteil hat.
the chances are it would still have some (though relatively little) upside.
Dann nennen Sie bitte einige! Mindestens eine, anstatt eine Hypothese aufzustellen!
Es scheint mir, dass Fowlers größter Einwand darin besteht, dass ADMs im folgenden Sinne keine OO sind. Wenn man ein System "von Grund auf neu" um passive Datenstrukturen herum entwirft, die von anderen Codeteilen manipuliert werden, riecht dies sicherlich eher nach prozeduralem Design als nach objektorientiertem Design.
Ich schlage vor, dass es mindestens zwei Kräfte gibt, die diese Art von Design erzeugen können:
Designer / Programmierer, die immer noch der Meinung sind, dass prozedural erforderlich ist, um in einer objektorientierten Umgebung zu arbeiten (oder davon auszugehen, dass sie ...), um ein neues System zu erstellen , und
Entwickler, die daran arbeiten, einem Legacy- System, das nicht OO-fähig ist (unabhängig von der Sprache), ein serviceähnliches "Gesicht" zu verleihen.
Wenn Sie beispielsweise eine Reihe von Diensten erstellen, um die Funktionalität einer vorhandenen COBOL-Mainframe-Anwendung verfügbar zu machen, können Sie Dienste und Schnittstellen anhand eines konzeptionellen Modells definieren, das die internen COBOL-Datenstrukturen nicht widerspiegelt. Wenn der Dienst das neue Modell jedoch den alten Daten zuordnet, um die vorhandene, aber versteckte Implementierung zu verwenden, ist das neue Modell möglicherweise im Sinne von Fowlers Artikel "anämisch" - z. B. eine Reihe von Definitionen im TransferObject-Stil und Beziehungen ohne wirkliches Verhalten.
Diese Art von Kompromiss kann durchaus für die Grenzen üblich sein, an denen idealistisch reine OO-Systeme mit einer vorhandenen Nicht-OO-Umgebung interagieren müssen.
Das anämische Domänenmodell (ADM) ist möglicherweise eine gute Wahl, wenn Ihr Team nicht in der Lage oder nicht bereit ist, ein Rich-Domain-Modell (RDM) zu erstellen und es im Laufe der Zeit zu warten. Das Gewinnen mit einem RDM erfordert eine sorgfältige Beachtung der im System verwendeten dominanten Abstraktionen. Stellen Sie sich vor, dass in jeder Entwicklergruppe nicht mehr als die Hälfte und vielleicht nur ein Zehntel ihrer Mitglieder mit Abstraktionen kompetent sind. Wenn dieser Kader (möglicherweise nur ein einziger Entwickler) nicht in der Lage ist, Einfluss auf die Aktivitäten der gesamten Gruppe zu nehmen, wird das RDM der Entropie erliegen.
Und das entropische RDM tut besonders weh. Die Entwickler werden harte Lektionen lernen. Zunächst werden sie in der Lage sein, die Erwartungen ihrer Stakeholder zu erfüllen, da sie keine Geschichte haben, der sie gerecht werden können. Aber wenn ihr System komplizierter (nicht komplexer) wird , wird es spröde; Die Entwickler werden versuchen, Code wiederzuverwenden, neigen jedoch dazu, neue Fehler oder Rückverfolgungen in der Entwicklung hervorzurufen (und damit ihre Schätzungen zu überschreiten).
Im Gegensatz dazu werden die ADM-Entwickler geringere Erwartungen an sich selbst stellen, da sie nicht erwarten, so viel Code für neue Funktionen wiederzuverwenden. Mit der Zeit werden sie ein System mit vielen Inkonsistenzen haben, aber es wird wahrscheinlich nicht unerwartet kaputt gehen. Ihre Markteinführungszeit wird länger sein als bei einem erfolgreichen RDM, aber es ist unwahrscheinlich, dass ihre Stakeholder diese Möglichkeit wahrnehmen.
"Entwickler, die daran arbeiten, einem Legacy-System, das nicht von OO (unabhängig von der Sprache) entwickelt wurde, ein serviceähnliches" Gesicht "zu verleihen."
Wenn Sie an viele LOB-Anwendungen denken, verwenden diese Legacy-Systeme häufig nicht dasselbe Domänenmodell wie Sie. Das anämische Domänenmodell löst dieses Problem mithilfe der Geschäftslogik in Serviceklassen. Sie könnten all diesen Schnittstellencode in Ihr Modell einfügen (im herkömmlichen OO-Sinne) - aber normalerweise verlieren Sie die Modularität.
Als ich zum ersten Mal auf den Artikel über das Anemic Domain Model stieß, dachte ich: "Holy S ***, das ist was ich tue. Horror!" Ich beharrte und folgte den Verweisen auf Eric Evans Buch, das als gutes Beispiel angesehen wurde, und lud die Quelle herunter. Es stellt sich heraus, dass "kein anämisches Domänenmodell verwenden" nicht bedeutet, "keine Serviceklassen zu verwenden, keine Mediatoren zu verwenden, keine Strategien zu verwenden" oder sogar "der manipulierten Klasse Logik zu verleihen".
Die DDD-Beispiele enthalten Serviceklassen, XyzUpdaters, Singletons und IoC.
Ich bin immer noch verwirrt darüber, was genau ein anämisches Domänenmodell ist. Ich erwarte "Ich werde es wissen, wenn ich es sehe". Im Moment bin ich zufrieden mit einem positiven Beispiel für gutes Design.
Nachdem ich mit einem "ausgereiften" System mit einem ADM gearbeitet habe und das Gefühl habe, dass ich zumindest ein anekdotisches Feedback zu dieser Frage geben kann.
1) Fehlende Verkapselung
In einem Live-System mit einem ADM besteht die Möglichkeit, zB 'obj.x = 100; obj.save ', auch wenn dies gegen die Geschäftslogik verstößt. Dies führt zu einer Reihe von Fehlern, die nicht auftreten würden, wenn die Invarianten dem Objekt nachempfunden wären. Es ist die Schwere und Verbreitung dieser Fehler, die meiner Meinung nach das schwerwiegendste Negativ für ein ADM sind.
Ich halte es für wichtig, hier darauf hinzuweisen, dass sich hier eine funktionale Lösung und die prozeduralen Lösungen eines ADM erheblich unterscheiden und dass alle Ähnlichkeiten, die andere möglicherweise mit den Oberflächenähnlichkeiten zwischen einem ADM und einer funktionalen Lösung gezogen haben, zufällig sind.
2) Code aufblähen
Ich schätze, dass die in einem ADM erzeugte Codemenge das 5- bis 10-fache der Menge beträgt, die eine OOP / RDM-Lösung erzeugen würde. Dies ist darauf zurückzuführen, dass möglicherweise 50% Code-Wiederholungen, 30% Kesselplatten-Codes und 20% Probleme oder Probleme lösen, die sich aus dem Fehlen eines RDM ergeben.
3) Schlechtes Verständnis der Domänenprobleme
Ein ADM und ein schlechtes Verständnis der Domänenprobleme gehen etwas Hand in Hand. Es entstehen naive Lösungen, Anforderungen werden aufgrund der Schwierigkeit, sie mit dem vorhandenen DM zu unterstützen, nur unzureichend berücksichtigt, und das ADM wird aufgrund der längeren Entwicklungszeiten und der mangelnden Flexibilität zu einem erheblichen Hindernis für Unternehmensinnovationen.
4) Wartungsschwierigkeiten
Ein gewisses Maß an Genauigkeit ist erforderlich, um sicherzustellen, dass ein Domänenkonzept an allen Stellen geändert wird, an denen es zum Ausdruck gebracht wird, da das Konzept möglicherweise nicht nur eine Neuimplementierung durch Kopieren und Einfügen ist. Dies führt häufig dazu, dass dieselben Fehler mehrfach untersucht und behoben werden.
5) Erhöhte Schwierigkeit beim Einsteigen
Ich denke, einer der Vorteile eines RDM ist der Zusammenhalt von Konzepten, die ein schnelleres Verständnis der Domäne ermöglichen. Mit einem ADM können Konzepte fragmentiert und unklar sein, was für neue Entwickler schwieriger zu erwerben ist.
Ich war auch versucht, die Betriebsunterstützungskosten für ein ADM höher einzubeziehen als für ein RDM, aber dies würde von einer Reihe von Faktoren abhängen.
Wie andere bereits betont haben, sollten Sie sich bei DDD (Greg Evans, Vince Vaughn und Scott Millett) nach den Vorteilen eines RDM umsehen.
Es ist der gleiche Profi wie bei den meisten Anti-Patterns: Es ermöglicht Ihnen, viele Leute für eine lange Zeit zu beschäftigen. Da Manager tendenziell mehr bezahlt werden, wenn sie mehr Mitarbeiter verwalten, besteht ein starker Anreiz, sich nicht zu verbessern.
In Übereinstimmung mit der Antwort von Eric P und dem, was einige andere oben geschrieben haben, scheint der Hauptnachteil eines ADM der Verlust von OOD zu sein, insbesondere das Zusammenhalten der Logik und der Daten eines Domänenkonzepts, so dass die Implementierungsdetails währenddessen verborgen bleiben Die API kann reichhaltig sein.
Eric weist darauf hin, dass es häufig Informationen außerhalb einer Domänenklasse gibt, die für die Logik des Handelns auf diese Klasse erforderlich sind, z. B. die Überprüfung eines Inventars vor dem Hinzufügen eines Artikels zu einer Bestellung. Ich frage mich jedoch, ob die Antwort eine Service-Schicht ist, die diese übergreifende Logik enthält, oder ob sie im Rahmen des Objektdesigns besser gehandhabt wird. Jemand muss etwas über das Inventarobjekt, das Produktobjekt und das Bestellobjekt wissen. Vielleicht ist es einfach ein OrderSystem-Objekt, das ein Inventarmitglied, eine Liste von Bestellungen usw. hat. Dies sieht nicht sehr anders aus als ein Service, aber ich denke, es ist konzeptionell kohärenter.
Oder sehen Sie es so: Sie können einen Benutzer mit einem internen Guthaben haben, und jedes Mal, wenn User.addItemToOrder (Artikel) aufgerufen wird, wird der Preis des Artikels abgerufen und das Guthaben überprüft, bevor es hinzugefügt wird usw. Dies scheint eine vernünftige OO zu sein Design. Ich bin mir nicht sicher, was genau verloren geht, wenn ich das durch Service.addItemToUserOrder (Benutzer, Element) ersetze, aber ich bin mir auch nicht sicher, was gewonnen wurde. Ich denke, ein Verlust wäre die zusätzliche Codeebene sowie der klobigere Schreibstil und die erzwungene Unkenntnis des zugrunde liegenden Domänenmodells.
Es sollte beachtet werden, dass die Kapselung und Konsolidierung von Schnittstellenpunkten, die durch ein gut gestaltetes Objektmodell für die Nachrichtenübermittlung bereitgestellt wird, mit zunehmender Komplexität und Granularität der Variationen die Sicherheit und das Verwalten von kritischem Code ohne umfassendes Refactoring wesentlich sicherer macht.
Die vom ADM erstellten Serviceschichten sind zwar sicherlich einfacher zu implementieren (da sie relativ wenig Überlegungen erfordern und über viele dezentrale Schnittstellenpunkte verfügen), werden jedoch wahrscheinlich später Probleme verursachen, wenn es an der Zeit ist, ein lebendes und wachsendes System zu ändern.
Ich könnte auch hinzufügen, dass nicht in allen Fällen überhaupt ein Domänenmodell erforderlich ist (geschweige denn das ADM-Modell). Manchmal ist es besser, einen prozeduraleren / funktionaleren Stil der Aufgabe zu verwenden, der datengesteuert ist und nicht von anwendungsweiten Logik- / Geschäftsregeln abhängt.
Wenn Sie versuchen, die Vor- und Nachteile für eine ganze App zu bestimmen, ist es meiner Meinung nach wichtig, zuerst zu entwerfen, wie jede für Ihre bestimmte Anwendung aussehen könnte, bevor Sie überhaupt mit dem Schreiben einer einzelnen Codezeile beginnen. Wenn Sie Ihre Anwendung in beiden Stilen CRC- oder drahtgebunden haben, treten Sie einen Schritt zurück und entscheiden Sie, welche sinnvoller ist und besser zur Anwendung passt.
Überlegen Sie auch, welche leichter zu warten ist ...
Es gibt eine bessere Vorhersagbarkeit. Manager mögen das, besonders wenn das Projekt Zeit und Material bezahlt. Jede Änderung bedeutet viel Arbeit, so dass schwierige Arbeit hinter viel sich wiederholender Arbeit verborgen sein kann. In einem gut konzipierten DRY-System ist die Vorhersagbarkeit sehr schlecht, da Sie ständig neue Dinge tun.
Nachdem ich Eric Evans Buch über domänengesteuertes Design zum ersten Mal gelesen hatte, verstand ich nicht wirklich, dass es sich nicht nur um eine Reihe taktischer Muster für das Entwerfen guter Domänenmodellklassen handelt.
Nachdem ich mehr über das Thema gelernt und auch die strategischen Muster verwendet hatte, begann ich endlich zu verstehen, dass es zunächst darum geht, ein tiefes Verständnis für die Geschäftsprobleme zu erlangen, die Sie zu lösen versuchen.
Und erst danach können Sie entscheiden, welche Teile des Systems für die Anwendung taktischer Muster wie Aggregate, Entitäten , Repositorys usw. zusammen mit sogenannten Rich- Domain-Modellen (im Gegensatz zu anämischen ) geeignet sind . Um von diesen Mustern zu profitieren, muss die Geschäftslogik jedoch ausreichend komplex sein für diesen Teil des Systems sein.
Wenn es darum geht, die Lösung des vorliegenden Problems zu implementieren, sollte zunächst festgestellt werden, ob dieses spezifische Problem besser mit einem CRUD- basierten Ansatz oder einer Investition in ein umfangreiches Domänenmodell zusammen mit den genannten taktischen Mustern angegangen werden kann.
Wenn CRUD sinnvoller ist, z. B. wenn es keine komplexe Geschäftslogik gibt und der größte Teil der Logik sich mit der Transformation, Übertragung und Speicherung von Daten befasst, kann die Implementierung eines Domänenmodells ein unnötiger Overkill sein. Dies bedeutet nicht, dass nicht viel Arbeit zu erledigen ist, sondern nur, dass nicht die Geschäftsregeln den größten Implementierungsaufwand verursachen. Aber in diesem Fall gibt es nicht so etwas wie ein anämisches Domänenmodell , einfach weil es kein Domain - Modell überhaupt ist . Was Sie eher sehen werden, sind solche Dinge wie DTOs (Data Transfer Objects) oder DAOs(Datenzugriffsobjekte) und Serviceklassen, die die Daten verarbeiten. Und die entsprechenden Operationen befassen sich in hohem Maße mit der Transformation von Daten von einer Darstellung in eine andere und dem Verschieben von Daten mit sehr wenig oder fast keiner Geschäftslogik.
Wenn Sie festgestellt haben, dass es eine Menge komplexer Geschäftslogik gibt, die sich auch im Laufe der Zeit ändern wird, als wenn Sie in ein Domain-Modell investieren meiner Erfahrung nach eine gute Idee. Der Grund dafür ist, dass es einfacher ist, die Geschäftsperspektive über Code darzustellen und die entsprechenden Vorgänge zu verstehen, die die Geschäftsdomäne und ihre Regeln widerspiegeln. Dies bedeutet nicht, dass in jedem Anwendungsfall Domänenmodellklassen vorhanden sein müssen. Wenn zum Beispiel kein Zustand vorhanden ist, der mutiert und beibehalten werden soll, können auch nur Domänendienste, die die Domänenlogik enthalten, eher wie reine Funktionen implementiert werden.
Wenn es jedoch auch einen zu mutierenden und fortbestehenden Zustand gibt, der auch im Geschäftsbereich Zweck und Bedeutung hat, sollten der Zustand und das Verhalten, das diesen Zustand ändert, gekapselt werden . Damit kann niemand die Geschäftsregeln so einfach umgehen und dadurch zu ungültigen Zuständen und schwerwiegenden Fehlern führen. Sogenannte anämische Domänenmodelle sind häufig Ursachen für solche Probleme . Dies ist häufig der Fall, wenn Sie Code sehen, in dem verschiedene Komponenten mit derselben "anämischen" Domänenmodellklasse arbeiten und einen Teil ihres Status überprüfen und einen Teil ihres Status ändern, ohne sich um die Gesamtinvarianten dieser Geschäftseinheit zu kümmern oder diese zu kennen. Es ist nicht notwendig, dies als Anti-Muster zu bezeichnen, aber es ist wichtig, das zu verstehenSie verlieren viele Vorteile von Rich Domain-Modellenin einem DDD-basierten Ansatz zusammen mit den genannten Problemen. Wenn Sie ein Domänenmodell verwenden, bei dem das Verhalten und seine Daten in derselben Klasse platziert sind, können auch viele verschiedene "Clients" Operationen dieser Klasse aufrufen. Sie müssen jedoch nicht darauf achten, dass die Geschäftsinvarianten der Geschäftseinheit eingehalten werden Die Domain-Modellklasse kümmert sich immer darum und kann den "Client" auch über ungültige Operationen informieren oder sogar Ausnahmen als Sicherheitsnetz auslösen.
Unter dem Strich halte ich es daher für wichtig, Datenstruktur-ähnliche Klassen (wie DTOs oder DAOs) nicht mit anämischen Domänenmodellklassen zu verwechseln . Bei einem sorgfältig und absichtlich ausgewählten CRUD-basierten Ansatz ist es nicht vorteilhaft, ein Domänenmodell zu verwenden, da die Geschäftslogik zu komplex ist.
Mit dem anämischen Domänenmodell würde ich auf Code verweisen, aus dem hervorgeht, dass es viele komplexe Geschäftslogiken und Geschäftsregeln gibt, die auf verschiedene Komponenten verteilt sind und eher in der Nähe der Daten liegen sollten, die diese Logik ändert.
Es gibt noch eine weitere Lektion, die ich auf diesem Weg gelernt habe: Wenn Sie versuchen, dieselbe Geschäftssprache (auch als Ubiquituous Language bezeichnet ) in Ihrem Code zu verwenden, die die Steakhalter in ihrem täglichen Arbeitsleben verwenden, gewinnen Sie bereits so viele Vorteile hinsichtlich des Verständnisses von die Geschäftsdomäne und die Verbesserung der Lesbarkeit Ihres Codes, die Ihnen so viel hilft, egal ob Sie einen CRUD-basierten oder einen Domänenmodell-basierten Ansatz verwenden.
Um Michaels Antwort zu erweitern, hätte ich gedacht, dass es (ziemlich) klar ist, wohin dieser Code gehen soll: in einen dedizierten Mediator, der die Interaktion zwischen der Bestellung und dem Inventar übernimmt.
Aus meiner Sicht ist das Wichtigste an der Domain, dass sie das einfache Testverhalten der isInThisState()
Methoden usw. enthalten muss. Nach meiner Erfahrung sind diese in den meisten Unternehmen auch über die Service-Tränen (sic :) verteilt und werden entweder kopiert oder endlos neu geschrieben. All dies verstößt gegen die Standardkonhäsionsregeln.
Meiner Ansicht nach sollte der Ansatz sein Ziel für eine DM , die so viel von dem biz beahaviour hält als praktisch, leg den Rest in eindeutig gekennzeichneten Bereichen (dh nicht in den Diensten)
Mein Team persönlich bevorzugt das ADM. Wir haben eine Reihe von Geschäftsobjekten, die bestimmte Teile unserer Domäne darstellen. Wir verwenden Dienste, um diese Objekte in der Datenbank zu speichern. Unsere Geschäftsobjekte verfügen zwar über Methoden, diese Methoden manipulieren jedoch nur den internen Status.
Der Vorteil für uns bei der Verwendung von ADM gegenüber RDM zeigt sich darin, wie wir die Objekte in db beibehalten. Entwickler, die an unseren Legacy-Codesystemen arbeiten, können unsere Geschäftsobjekte (aus dem neuen System) verwenden und weiterhin ihre aktuelle Datenzugriffsschicht verwenden, um diese Objekte in der Datenbank zu speichern. Die Verwendung des RDM würde Entwickler unseres Legacy-Systems dazu zwingen, Repository-Objekte in unser Geschäftsmodell einzufügen ... was nicht mit ihrer aktuellen Datenzugriffsschicht übereinstimmt.
Ein anämisches Domänenmodell ist ein Anti-Muster. Anti-Patterns haben keine Profis.