Es gibt drei Varianten von Diensten : Domänendienste , Anwendungsdienste und Infrastrukturdienste .
- Domänendienste : Verkapselt
Geschäftslogik , die natürlich nicht in ein Domänenobjekt passt und KEINE typischen CRUD-Operationen sind - diese würden zu einem Repository gehören .
- Anwendungsdienste : Werden von externen Verbrauchern verwendet, um mit Ihrem System zu kommunizieren (denken Sie an Webdienste ). Wenn Verbraucher Zugang zu CRUD-Operationen benötigen, wären sie hier exponiert.
- Infrastrukturdienste : Werden verwendet, um technische Probleme (z. B. MSMQ, E-Mail-Anbieter usw.) zu abstrahieren.
Es ist sinnvoll, Domänendienste zusammen mit Ihren Domänenobjekten zu behalten - sie konzentrieren sich alle auf die Domänenlogik. Und ja, Sie können Repositorys in Ihre Services einfügen.
Anwendungsdienste verwenden normalerweise sowohl Domänendienste als auch Repositorys, um externe Anforderungen zu bearbeiten.
Ich hoffe, das hilft!
(Wenn Sie keine Lust zum Lesen haben, finden Sie unten eine Zusammenfassung :-)
Auch ich habe mit der genauen Definition von Anwendungsdiensten zu kämpfen. Obwohl Vijays Antwort vor einem Monat für meinen Denkprozess sehr hilfreich war, bin ich mit einem Teil davon nicht einverstanden.
Andere Ressourcen
Es gibt nur sehr wenige Informationen zu Anwendungsdiensten. Themen wie aggregierte Roots, Repositorys und Domänendienste werden ausführlich behandelt, Anwendungsdienste werden jedoch nur kurz erwähnt oder ganz weggelassen.
Der Artikel im MSDN-Magazin Eine Einführung in das domänengesteuerte Design beschreibt Anwendungsdienste als eine Möglichkeit, Ihr Domänenmodell zu transformieren und / oder externen Clients zur Verfügung zu stellen, z. B. als WCF-Dienst. So beschreibt Vijay auch Anwendungsdienste. Aus dieser Sicht sind Anwendungsdienste eine Schnittstelle zu Ihrer Domain .
Jeffrey Palermos Artikel über die Zwiebelarchitektur (Teil eins , zwei und drei ) sind eine gute Lektüre. Er behandelt Anwendungsdienste als Konzepte auf Anwendungsebene , z. B. als Benutzersitzung. Obwohl dies meinem Verständnis von Anwendungsdiensten näher kommt, entspricht es immer noch nicht meinen Gedanken zu diesem Thema.
Meine Gedanken
Ich stelle mir Anwendungsdienste als Abhängigkeiten vor, die von der Anwendung bereitgestellt werden . In diesem Fall kann die Anwendung eine Desktopanwendung oder ein WCF-Dienst sein.
Domain
Zeit für ein Beispiel. Sie beginnen mit Ihrer Domain. Hier werden alle Entitäten und Domänendienste implementiert, die nicht von externen Ressourcen abhängig sind. Alle Domänenkonzepte, die von externen Ressourcen abhängen, werden von einer Schnittstelle definiert. Hier ist ein mögliches Lösungslayout (Projektname fett gedruckt):
Die Klassen
Product
undProductFactory
wurden in der Kernassembly implementiert. DasIProductRepository
ist etwas, das wahrscheinlich von einer Datenbank unterstützt wird. Die Implementierung ist nicht das Anliegen der Domäne und wird daher durch eine Schnittstelle definiert.Im Moment konzentrieren wir uns auf die
IExchangeRateService
. Die Geschäftslogik für diesen Dienst wird von einem externen Webdienst implementiert. Das Konzept ist jedoch immer noch Teil der Domäne und wird durch diese Schnittstelle dargestellt.Infrastruktur
Die Implementierung der externen Abhängigkeiten ist Teil der Infrastruktur der Anwendung:
XEExchangeRateService
implementiert denIExchangeRateService
Domänendienst durch Kommunikation mit xe.com . Diese Implementierung kann von Ihren Anwendungen verwendet werden, die Ihr Domänenmodell verwenden, einschließlich der Infrastrukturassembly.Anwendung
Beachten Sie, dass ich Anwendungsdienste noch nicht erwähnt habe. Wir werden uns diese jetzt ansehen. Angenommen, wir möchten eine
IExchangeRateService
Implementierung bereitstellen , die einen Cache für schnelle Suchvorgänge verwendet. Der Umriss dieser Dekorateurklasse könnte so aussehen.Beachten Sie den
ICache
Parameter? Dieses Konzept ist nicht Teil unserer Domain, es ist also kein Domain-Service. Es ist ein Anwendungsdienst . Dies ist eine Abhängigkeit unserer Infrastruktur, die möglicherweise von der Anwendung bereitgestellt wird. Lassen Sie uns eine Anwendung vorstellen, die dies demonstriert:Dies alles kommt in der Anwendung wie folgt zusammen:
Zusammenfassung
Eine vollständige Anwendung besteht aus drei Hauptschichten:
Die Domänenschicht enthält die Domänenentitäten und eigenständigen Domänendienste. Jegliche Domain - Konzepte (einschließlich Domain - Services, sondern auch Repositories) , die auf externen Ressourcen abhängig sind , werden durch Schnittstellen definiert.
Die Infrastrukturschicht enthält die Implementierung der Schnittstellen aus der Domänenschicht. Diese Implementierungen können neue einführen Nicht-Domain - Abhängigkeiten, die die Anwendung zur Verfügung gestellt werden müssen. Dies sind die Anwendungsdienste und werden durch Schnittstellen dargestellt.
Die Anwendungsschicht enthält die Implementierung der Anwendungsdienste. Die Anwendungsschicht kann auch zusätzliche Implementierungen von Domänenschnittstellen enthalten, wenn die von der Infrastrukturschicht bereitgestellten Implementierungen nicht ausreichen.
Obwohl diese Perspektive möglicherweise nicht mit der allgemeinen DDD-Definition von Diensten übereinstimmt, trennt sie die Domäne von der Anwendung und ermöglicht es Ihnen, die Domänen- (und Infrastruktur-) Assembly für mehrere Anwendungen freizugeben.
quelle
IExchangeRateService
Schnittstelle? Dies ist ein Domain-Konzept, dh etwas, das in der allgegenwärtigen Sprache Ihres Kunden enthalten ist. Andere Teile Ihrer Domain können von diesem Service abhängen, weshalb seine Schnittstelle in der Domain-Schicht definiert ist. Da die Implementierung jedoch einen externen Webdienst umfasst, befindet sich die implementierende Klasse in der Infrastrukturschicht. Auf diese Weise befasst sich die Domänenschicht nur mit der Geschäftslogik.ExchangeRate
Instanz sein, die eine Basiswährung, eine Gegenwährung und den Wechselkurswert zwischen diesen beiden Währungen enthält. Diese eng miteinander verbundenen Werte stellen das Wechselkurskonzept der Domäne dar, sodass diese in der Domänenschicht leben. Obwohl es wie ein einfaches DTO erscheint, wird es in DDD als Wertobjekt bezeichnet und kann zusätzliche Geschäftslogik zum Vergleichen oder Transformieren von Instanzen enthalten.Die beste Ressource, die mir geholfen hat, den Unterschied zwischen einem Anwendungsdienst und einem Domänendienst zu verstehen, war die Java-Implementierung des hier gefundenen Frachtbeispiels von Eric Evans . Wenn Sie es nicht herunterladen, können Sie die Interna von RoutingService (einem Domänendienst) und BookingService, CargoInspectionService (Application Services) überprüfen.
Mein 'Aha'-Moment wurde durch zwei Dinge ausgelöst:
Lesen Sie die Beschreibung der Dienste im obigen Link, genauer diesen Satz:
Lesen Sie diesen Blog-Beitrag , insbesondere diesen Teil:
quelle
Der Domänendienst ist die Erweiterung der Domain. Es sollte nur im Kontext der Domain gesehen werden. Dies ist keine Benutzeraktion wie zum Beispiel ein Konto schließen oder so. Der Domänendienst passt dort, wo es keinen Status gibt. Andernfalls wäre es ein Domänenobjekt. Der Domänendienst leistet etwas, das nur dann sinnvoll ist, wenn er mit anderen Mitarbeitern (Domänenobjekten oder anderen Diensten) durchgeführt wird. Und das macht Sinn und liegt in der Verantwortung einer anderen Schicht.
Anwendungsdienst ist die Schicht, die die Interaktion zwischen den Domänenobjekten und -diensten initialisiert und überwacht. Der Ablauf sieht im Allgemeinen folgendermaßen aus: Domänenobjekt (oder Objekte) aus dem Repository abrufen, eine Aktion ausführen und dort ablegen (oder nicht). Es kann mehr - zum Beispiel kann es prüfen, ob ein Domänenobjekt vorhanden ist oder nicht, und Ausnahmen entsprechend auslösen. Auf diese Weise kann der Benutzer mit der Anwendung interagieren (und von dort stammt wahrscheinlich der Name), indem Domänenobjekte und -dienste bearbeitet werden. Anwendungsdienste sollten im Allgemeinen alle möglichen Anwendungsfälle darstellen. Das Beste, was Sie tun können, bevor Sie über die Domäne nachdenken, ist wahrscheinlich, Anwendungsdienstschnittstellen zu erstellen, die Ihnen einen viel besseren Einblick in das geben, was Sie wirklich versuchen. Mit diesem Wissen können Sie sich auf die Domäne konzentrieren.
Repositorys können im Allgemeinen in Domänendienste eingefügt werden, dies ist jedoch ein eher seltenes Szenario. Es ist jedoch die Anwendungsschicht, die dies die meiste Zeit tut.
quelle
Aus dem Red Book (Implementing Domain Driven Design, von Vaughn Vernon) verstehe ich die Konzepte folgendermaßen:
Domänenobjekte ( Entitäten und Wertobjekte ) kapseln das von der (Unter-) Domäne geforderte Verhalten und machen es natürlich, ausdrucksstark und verständlich.
Domänendienste kapseln solche Verhaltensweisen, die nicht in ein einzelnes Domänenobjekt passen . Beispielsweise kann eine Buchbibliothek, die a
Book
an aClient
(mit entsprechendenInventory
Änderungen) leiht , dies von einem Domänendienst aus tun.Anwendungsdienste behandeln den Ablauf von Anwendungsfällen, einschließlich aller zusätzlichen Bedenken, die zusätzlich zu den Domänen erforderlich sind . Solche Methoden werden häufig über ihre API für den Verbrauch durch externe Clients verfügbar gemacht. Um auf unserem vorherigen Beispiel aufzubauen, stellt unser Anwendungsdienst möglicherweise eine Methode bereit
LendBookToClient(Guid bookGuid, Guid clientGuid)
, die:Client
.Book
.Client
undBook
), um die eigentliche Domänenlogik für das Ausleihen des Buches an den Client zu übernehmen. Ich stelle mir zum Beispiel vor, dass die Bestätigung der Verfügbarkeit des Buches definitiv Teil der Domänenlogik ist.Ein Anwendungsdienst sollte im Allgemeinen einen sehr einfachen Ablauf haben. Komplexe Anwendungsdienstabläufe weisen häufig darauf hin, dass die Domänenlogik aus der Domäne ausgetreten ist.
Wie Sie hoffentlich sehen können, bleibt das Domain-Modell auf diese Weise sehr sauber und ist leicht zu verstehen und mit den Domain-Experten zu diskutieren, da es nur seine eigenen, tatsächlichen geschäftlichen Bedenken enthält. Der Anwendungsfluss , auf der anderen Seite, ist auch viel einfacher zu handhaben , da es von Domain betrifft entlastet wird, und wird präzise und unkompliziert.
quelle
Millett, C (2010). Professionelle ASP.NET-Entwurfsmuster. Wiley Publishing. 92.
quelle
Domänendienste : Ein Dienst, der eine Geschäftslogik ausdrückt , die nicht Teil eines aggregierten Stamms ist.
Sie haben 2 Aggregate:
Product
welches Name und Preis enthält.Purchase
Hier finden Sie das Kaufdatum, eine Liste der bestellten Produkte mit Menge und Produktpreis zu diesem Zeitpunkt sowie die Zahlungsmethode.Checkout
ist nicht Teil eines dieser beiden Modelle und ist ein Konzept in Ihrem Unternehmen.Checkout
kann als Domänendienst erstellt werden, der alle Produkte abruft und den Gesamtpreis berechnet, den Gesamtbetrag bezahlt, indem er einen anderen DomänendienstPaymentService
mit einem Implementierungsteil der Infrastruktur aufruft und in diesen konvertiertPurchase
.Anwendungsdienste : Ein Dienst, der Domänenmethoden "orchestriert" oder ausübt. Dies kann so einfach sein wie nur Ihr Controller.
Dies ist der Ort, an dem Sie normalerweise Folgendes tun:
Sie können hier Validierungen durchführen, z. B. prüfen, ob a
Product
eindeutig ist. Sofern einProduct
eindeutiges Wesen keine Invariante ist, sollte dies Teil des Domänendienstes sein, der möglicherweise aufgerufen wird,UniqueProductChecker
da es nicht Teil derProduct
Klasse sein kann und mit mehreren Aggregaten interagiert.Hier ist ein vollständiges Beispiel für ein DDD-Projekt: https://github.com/VaughnVernon/IDDD_Samples
Sie finden viele Beispiele für Anwendungsdienste und einige Domänendienste
quelle
Stellen Sie sich einen Domänendienst als ein Objekt vor, das Geschäftslogik oder mit Geschäftsregeln verbundene Logik für Domänenobjekte implementiert. Diese Logik lässt sich nur schwer in dieselben Domänenobjekte einfügen und verursacht auch keine Statusänderung des Domänendienstes (Domänendienst ist ein Objekt ohne ein "Status" oder besser ohne einen Status, der eine geschäftliche Bedeutung hat), aber schließlich den Status nur der Domänenobjekte ändert, auf denen gearbeitet wird.
Während ein Anwendungsdienst Logik auf Anwendungsebene als Benutzerinteraktion, Eingabevalidierung implementiert, bezieht sich die Logik nicht auf das Geschäft, sondern auf andere Belange: Authentifizierung, Sicherheit, E-Mail usw., und beschränkt sich darauf, einfach Dienste zu verwenden, die von Domänenobjekten verfügbar gemacht werden.
Ein Beispiel hierfür könnte das folgende Szenario sein, das nur zur Erläuterung gedacht ist: Wir müssen eine sehr kleine Domotic Utility-App implementieren, die eine einfache Operation ausführt, dh "das Licht einschalten, wenn jemand die Tür eines Hauszimmers öffnet, um einzutreten." in und schalten Sie das Licht aus, wenn Sie die Tür schließen, die aus dem Raum austritt ".
Vereinfachen viel wir nur 2 Domain Einheiten betrachten:
Door
undLamp
jeder von ihnen hat zwei Zustände, respectevelyopen/closed
undon/off
und spezifischen Methoden Zustandsänderungen an ihnen zu arbeiten.In diesem Fall benötigen wir einen Domänendienst, der die spezifische Operation zum Einschalten des Lichts ausführt, wenn jemand die Tür von außen öffnet, um in einen Raum zu gelangen, da die Tür und die Lampenobjekte diese Logik nicht auf eine Weise implementieren können, die wir für geeignet halten zu ihrer Natur .
Wir können unsere Domain Service wie aufrufen
DomoticDomainService
und 2 Methoden implementieren:OpenTheDoorAndTurnOnTheLight
undCloseTheDoorAndTurnOffTheLight
diese zwei Methoden ändern respectevely den Zustand der beiden ObjekteDoor
undLamp
zuopen/on
undclosed/off
.Der Status des Ein- oder Ausstiegs aus einem Raum ist im Domänendienstobjekt und auch nicht in den Domänenobjekten vorhanden, wird jedoch als einfache Benutzerinteraktion von einem Anwendungsdienst
HouseService
implementiert , den wir möglicherweise aufrufen und der einige Ereignishandler als implementiertonOpenRoom1DoorToEnter
undonCloseRoom1DoorToExit
usw. für jeden Raum (dies ist nur ein Beispiel zur Erläuterung des Zwecks) , die sich jeweils auf Anrufdomänendienstdienste zur Ausführung des besuchten Verhaltens beziehen (wir haben die Entität nicht berücksichtigt,Room
da es sich nur um ein Beispiel handelt). .Dieses Beispiel, das weit davon entfernt ist, eine gut gestaltete Anwendung in der realen Welt zu sein, hat (wie bereits mehrfach erwähnt) den einzigen Zweck, zu erklären, was ein Domänendienst und sein Unterschied zu einem Anwendungsdienst sind. Ich hoffe, er ist klar und nützlich.
quelle