Als ich IoC Container in meinem letzten Projekt verwendet habe, bin ich zu anämischen Entitäten und dem größten Teil meiner Geschäftslogik in Stateless Services gekommen.
Ich habe Projekte von anderen Entwicklern gesehen, die "Inversion of Control" verwenden und die immer "anämisch" sind.
Ist es möglich, IoC und Rich Domain zu verwenden, da das "anämische Domänenmodell" ein Antimuster ist? Gibt es dafür gute Beispiele, Open-Source-Projekte?
dependency-injection
Mag20
quelle
quelle
Antworten:
Für den Anfang: DI und IoC sind keine Synonyme. Es tut mir leid, aber ich muss darauf hinweisen (es scheint mir, dass Sie denken, dass sie sind).
Wie für Ihre Anfrage ... Nun, Dependency Injection ist nur ein Werkzeug. Wie Sie dieses Tool verwenden, ist eine völlig andere Sache. Es gibt auch andere Tools (Entwurfsmuster), die das Problem beheben können. Ich bin zum Beispiel der Meinung, dass eine breite Akzeptanz des MVC-Musters einer der Schlüssel zur Bildung des Antimusters des anämischen Domänenmodells ist: Controller (in einfacheren Anwendungen, in komplizierteren Anwendungen, die eine zusätzliche Service-Schicht darstellen würden) übernehmen die Verantwortung für die Validierung von Geschäftsregeln Dies erzwingt sie ebenso wie die Umwandlung von DB-Entitäten in nützliche Funktionen, während Business Layer zu einer einfachen Datenzugriffsschicht wird, die einfaches ORM mit einer Eins-zu-Eins-Zuordnung zu Datenbankentitäten ist.
Natürlich gestalten Sie Ihre Anwendung so, dass Sie nach Belieben ein korrektes Domänenmodell erstellen können, und all diese IoCs, DIs und MVCs halten Sie nicht auf. Was dich aufhalten könnte, ist dein Team. Sie müssen sie irgendwie davon überzeugen, den richtigen Weg einzuschlagen, und es kann schwierig sein, da viele Softwareentwickler keinen starken architektonischen Hintergrund haben.
quelle
Bei den meisten (wenn nicht allen) Anwendungen handelt es sich um eine Mischung aus Infrastruktur- und Domänenproblemen. Wenn Sie ein bestimmtes Maß an Komplexität erreichen, können Sie die Verwaltung vereinfachen, wenn die Domäne von der Infrastruktur getrennt ist, sodass Sie leichter überlegen und sich unabhängig voneinander entwickeln können.
Natürlich muss das Domänenmodell immer noch mit dem Rest des Systems kommunizieren, und dies wird normalerweise bei zustandslosen Diensten (die Teil der Domäne sind) der Fall sein, bei denen Infrastrukturprobleme (z. B. Datenbankzugriff) auftreten. Die Verwendung eines IoC-Containers entfernt diese Abhängigkeit nicht, sondern verschiebt seine Konfiguration in einen separaten Bereich.
Die Entitäten speichern den Status und sollten für die Geschäftsregeln verantwortlich sein. Wenn Ihre Dienste alle Invarianten und andere Geschäftsregeln durchsetzen, ist es wahrscheinlich, dass sich die Logik am falschen Ort befindet.
Wenn Sie die Logik an den richtigen Stellen haben und dennoch Services erhalten, die nichts anderes sind als Wrapper für Infrastruktur-Dinge und -Entitäten, die nur Eigentum sind, ist es sehr wahrscheinlich, dass die Domäne nicht komplex genug ist, um dies zu rechtfertigen der Overhead eines eigenen Modells. Fast alles, was Sie über DDD lesen, enthält einen Haftungsausschluss, der eigentlich nur für komplexe Domänen gedacht ist, der jedoch allzu oft vergessen zu werden scheint.
quelle
Gehe zur Quelle. Beginnen Sie mit Fowlers Beitrag über anämische Domänenmodelle . Er verweist auf Eric Evans Domain Driven Design als ein Beispiel für eine gute Praxis. Der Quellcode dafür ist hier . Lade es herunter.
Beachten Sie, dass Inversion of Control verwendet wird (Suche nach @Autowired), Serviceklassen (BookingService) und "Business Process" -Klassen (z. B. ItAdvisorUpdater) vorhanden sind.
Fowlers Originalartikel beginnt den Weg zu dem Beispiel, das Sie suchen.
quelle
VoyageRepositoryHibernate
hängt die Klasse, die in die Infrastrukturebene eingefügt wurde, tatsächlich jedoch von der Domänenebene ab.save(foo)
Code implementieren , der sich ändern kann, wenn sich das Domänenmodell ändert (wenn beispielsweise ein neues Attribut hinzugefügt wirdMyDomainObject
), muss er (per Definition) zur Domänenschicht gehören. Ansonsten kann man einfach nicht mehr über "Ebenen" sprechen.Ich nehme an, Sie meinen DI anstelle von IoC, und das Projekt, an dem Sie gearbeitet haben, verwendet einen DI-Container wie Spring. IoC hat zwei Hauptvarianten: DI und Locator-Muster. Ich verstehe nicht, warum das Locator-Muster ein Problem sein sollte, also konzentrieren wir uns auf DI.
Ich denke nicht, dass es möglich ist oder zumindest sehr unpraktisch wäre. Der Hauptaspekt von DI-Containern besteht darin, dass sie die Erstellung von Objekten steuern, wenn sie in andere Objekte ("verwaltete Objekte") eingefügt werden. Die Gruppe verwalteter Objekte, die bei Ausführung des Projekts aktiv ist, ist unabhängig davon, welche Domänenelemente in Ihrem Projekt vorhanden sind, hängt jedoch davon ab, wie Objekte verkabelt sind und welche Bereiche (Singleton, Prototyp) ihnen zugewiesen sind.
Aus diesem Grund möchten Sie nicht, dass der DI-Container Ihre Domänenobjekte verwaltet. Wenn Sie Objekte jedoch manuell erstellen (mit new), können Sie keine anderen Objekte in Ihre Domänenobjekte einfügen. (Potenzielle Umgehungsmöglichkeiten mit manueller Verkabelung bleiben hiervon unberührt.) Da Sie diese Injektionen benötigen, um Implementierungen durch andere zu ersetzen, können Sie die Funktionalität von Rich-Domain-Objekten mit DI nicht ersetzen. Daher möchten Sie keine Funktionalität in Domänenobjekte einfügen, oder Sie würden die Funktionen der DI verlieren.
Ich verstehe nicht, wie ein hypothetischer DI-Container funktionieren könnte, der Ihre Objekte nicht verwaltet, und keine der vorhandenen Implementierungen lässt dies zu. Man kann also mit Recht behaupten, dass DI auf die Verwaltung von Objekten angewiesen ist. Sie werden daher immer versucht, potenzielle Rich Domain-Objekte in eine anämische Klasse und eine oder mehrere Transaktionsskriptklassen aufzuteilen.
quelle