381 Stimmen

Domain Driven Design: Domänendienst, Anwendungsdienst

Kann mir jemand den Unterschied zwischen Domain- und Anwendungsdiensten erklären, indem er einige Beispiele gibt? Und wenn ein Dienst ein Domänendienst ist, würde ich die tatsächliche Implementierung dieses Dienstes im Domänen-Assembly platzieren und wenn ja, würde ich auch Repositories in diesen Domänendienst einfügen? Einige Informationen wären wirklich hilfreich.

0 Stimmen

Fühlen Sie sich frei, dies zu überprüfen: youtu.be/MfEpw2WXXyk

18voto

Ciro Corvino Punkte 1796

Betrachten Sie einen Domain Service als ein Objekt, das Geschäftslogik oder geschäftsregelrelevante Logik auf Domänenobjekten implementiert und diese Logik schwer in die gleichen Domänenobjekte zu integrieren ist und auch keinen Zustandswechsel des Domain Service verursacht (Domain Service ist ein Objekt ohne "Zustand" oder besser gesagt ohne einen Zustand, der eine geschäftliche Bedeutung hat), sondern letztendlich nur den Zustand der Domänenobjekte ändert, auf denen er operiert.

Während ein Anwendungsdienst Logik auf Applikationsebene implementiert, wie Benutzerinteraktion, Eingabevalidierung, Logik, die nicht geschäftsbezogen ist, sondern andere Belange betrifft: Authentifizierung, Sicherheit, E-Mail-Versand usw., beschränkt er sich darauf, einfach die von Domänenobjekten bereitgestellten Dienste zu nutzen.

Ein Beispiel dafür könnte das folgende Szenario sein, das nur zum Erklärungszweck gedacht ist: wir müssen eine sehr kleine domotische Dienstprogramm-App implementieren, die eine einfache Operation ausführt, nämlich "das Licht einschalten, wenn jemand die Tür eines Zimmer eines Hauses öffnet, um einzutreten, und das Licht ausschaltet, wenn die Tür geschlossen wird und man das Zimmer verlässt".

Um es zu vereinfachen, betrachten wir nur 2 Domänenentitäten, die nicht Teil des gleichen Aggregats sind: Tür und Lampe, von denen jede 2 Zustände hat, nämlich offen/geschlossen und an/aus, und spezifische Methoden zur Durchführung von Zustandsänderungen an ihnen hat. Die Entitäten müssen Teil verschiedener Aggregate sein, so dass die folgende Logik nicht im Wurzelaggregat implementiert werden kann.

In diesem Fall benötigen wir einen Domain Service, der die spezifische Operation durchführt, das Licht einzuschalten, wenn jemand die Tür von außen öffnet, um in ein Zimmer einzutreten, weil die Tür- und Lampenobjekte diese Logik nicht in einer Weise implementieren können, die unserer Geschäftsnatur entspricht. Dieser neue Domain Service muss einige Geschäftsprozesse umschließen, die immer ausgelöst werden sollten, ausgelöst durch einige Domänenereignisse/-methoden.

Wir können unseren Domain Service als DomotikDomainService bezeichnen und 2 Methoden implementieren: TürÖffnenUndLichtEinschalten und TürSchließenUndLichtAusschalten, diese 2 Methoden ändern jeweils den Zustand beider Objekte Tür und Lampe in offen/an und geschlossen/aus.

Der Zustand des Eintretens oder Verlassens eines Raumes befindet sich nicht im Domain Service-Objekt und auch nicht in den Domänenobjekten, sondern wird als einfache Benutzerinteraktion durch einen Anwendungsdienst implementiert, den wir Hausdienst nennen können, der einige Ereignishandler wie beiÖffnenDerZimmertürEintreten und beiSchließenDerZimmertürVerlassen implementiert, und so weiter für jedes Zimmer (dies ist nur ein Beispiel zum Erklärungszweck...), die jeweils dafür verantwortlich sind, die Methoden des Domain Service aufzurufen, um das gewünschte Verhalten auszuführen (wir haben die Entität Zimmer nicht berücksichtigt, weil es nur ein Beispiel ist).

Dieses Beispiel, das bei weitem keine gut gestaltete Anwendung der realen Welt ist, hat nur den Zweck (wie bereits mehrmals gesagt), zu erklären, was ein Domain Service ist und wie er sich von einem Anwendungsdienst unterscheidet, hoffentlich ist es klar und nützlich.

Außerdem könnte der obige Beispiel-Domain Service leicht durch Domain-Ereignisse ersetzt werden, die verwendet werden, um explizit Nebeneffekte über ein oder mehrere Aggregate hinweg zu implementieren, aber da diese nicht Gegenstand dieser Frage sind, erwähne ich sie nur hier, damit der Leser sich ihrer Existenz bewusst ist und später entscheiden kann, welche Herangehensweise für sie besser ist.

7 Stimmen

Hallo Morteza, könntest du genauer sein? Dein Risiko besteht darin, nur ein "Urteil" ohne wirkliche Argumente zu sein. Danke

15voto

GorkemHalulu Punkte 2705

Dienstleistungen im Bereich Domain : Methoden, die nicht wirklich zu einer einzelnen Entität passen oder Zugriff auf das Repository erfordern, sind in Domain-Diensten enthalten. Die Domain-Service-Schicht kann auch eigene Domänenlogik enthalten und ist ebenso Teil des Domain-Modells wie Entitäten und Wertobjekte.

Anwendungsdienste : Der Anwendungsdienst ist eine schmale Schicht, die über dem Domänenmodell sitzt und die Anwendungsaktivität koordiniert. Er enthält keine Geschäftslogik und speichert nicht den Zustand von Entitäten; jedoch kann er den Zustand einer Geschäftsworkflow-Transaktion speichern. Sie verwenden einen Anwendungsdienst, um über das Request-Reply-Nachrichtenmuster eine API in das Domänenmodell bereitzustellen.

Millett,C (2010). Professional ASP.NET Design Patterns. Wiley Publishing. 92.

11voto

doesnotmatter Punkte 900

Dienstleistungen im Bereich Domäne: Ein Dienst, der eine Geschäftslogik ausdrückt, die nicht Teil eines Aggregate-Roots ist.

  • Sie haben 2 Aggregat:

    • Produkt enthält Name und Preis.
    • Kauf enthält Kaufdatum, Liste der bestellten Produkte mit Menge und Produktionspreis zu diesem Zeitpunkt und Zahlungsmethode.
  • Kasse gehört nicht zu diesen beiden Modellen und ist ein Konzept in Ihrem Unternehmen.

  • Kasse kann als ein Domänendienst erstellt werden, der alle Produkte abruft und den Gesamtpreis berechnet, den Gesamtpreis durch Aufruf eines anderen Domänendienstes Zahlungsdienst mit einer Implementierungsteil von Infrastruktur zahlt und es in Kauf umwandelt.

Anwendungsdienstleistungen: Ein Dienst, der "orchestriert" oder Domänenmethoden ausführt. Dies kann so einfach wie Ihr Controller sein.

Dies ist der Ort, an dem Sie normalerweise Folgendes tun:

public String createProduct(...einige Attribute) {
  if (productRepo.getByName(name) != null) {
    throw new Exception();
  }

  productId = productRepository.nextIdentity();

  product = new Product(productId, ...einige Attribute);

  productRepository.save(product);

  return productId.value();
  // oder Product selbst
  // oder einfach void, wenn Sie kein Interesse am Ergebnis haben
}

public void renameProduct(productId, newName) {
  product = productRepo.getById(productId);

  product.rename(newName);

  productRepo.save(product);
}

Sie können hier Validierungen vornehmen, z. B. prüfen, ob ein Produkt einzigartig ist. Es sei denn, dass ein einzigartiges Produkt eine Invariante ist, dann sollte dies Teil eines Domänendienstes sein, der möglicherweise UniqueProductChecker genannt wird, weil es nicht Teil der Klasse Produkt sein kann und mit mehreren Aggregaten interagiert.

Hier ist ein umfassendes Beispiel für ein DDD-Projekt: https://github.com/VaughnVernon/IDDD_Samples

Sie finden viele Beispiele für Anwendungsdienste und ein paar Domänendienste

0 Stimmen

Ist es zwingend erforderlich, Entitäten nur in Anwendungsdiensten zu validieren und zu speichern? Wenn ich die Entitäten A, B und C habe und sie alle miteinander verknüpft sind (A -> B -> C) und eine Operation auf A Änderungen an B und C verursachen soll, indem ein Domänenservice von einem anderen aufgerufen wird, wie mache ich das?

0 Stimmen

> Ist es zwingend erforderlich, Entitäten nur in Anwendungsdiensten zu validieren und zu speichern? Wenn Sie müssen, dann ja. Die meiste Zeit müssen Sie überprüfen, ob eine ID existiert, da Sie andernfalls mit einer Nullvariablen arbeiten würden.

1 Stimmen

Wenn ich Entitäten A, B und C habe und sie alle miteinander verbunden sind (A -> B -> C) und eine Operation auf A Änderungen an B und C verursachen soll, indem eine Domänendienst von einem anderen aus aufgerufen wird, wie mache ich das? Ich bin mir nicht sicher, was du mit "Aufruf eines Domänendienstes von einem anderen" meinst, aber für Reaktionen auf Änderungen einer Entität kannst du Events verwenden oder es einfach mit einem Anwendungsdienst wie: aggregateA.doOperation(), aggregateB.doAnother() orchestrieren. Suche nach: Orchestration vs Choreography.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X