Anwendungsschicht vs Domain-Schicht?


47

Ich lese Domain-Driven Design von Evans und bin gerade dabei, die geschichtete Architektur zu diskutieren. Ich habe gerade festgestellt, dass Anwendungs- und Domänenschicht unterschiedlich sind und getrennt werden sollten. In dem Projekt, an dem ich arbeite, sind sie irgendwie vermischt und ich kann den Unterschied nicht erkennen, bis ich das Buch gelesen habe (und ich kann nicht sagen, dass es mir jetzt sehr klar ist), wirklich.

Meine Fragen: Da beide die Logik der Anwendung betreffen und keine technischen und Präsentationsaspekte enthalten sollen, was sind die Vorteile des Zeichnens einer Grenze zwischen diesen beiden?

Antworten:


36

Ich habe vor kurzem DDD selbst gelesen. Als ich zu diesem Abschnitt kam, war ich angenehm überrascht, dass ich dieselbe 4-Schichten-Architektur entdeckte, die auch Evans hatte. Wie @lonelybug hervorhob, sollte die Domänenschicht vollständig vom Rest des Systems isoliert sein. Es muss jedoch etwas UI-spezifische Werte (Abfragezeichenfolgen, POST-Daten, Sitzung usw.) in Domänenobjekte übersetzen. Hier kommt die Anwendungsebene ins Spiel. Die Aufgabe besteht darin, zwischen der Benutzeroberfläche, der Datenschicht und der Domäne hin und her zu übersetzen und die Domäne effektiv vor dem Rest des Systems zu verbergen.

Ich sehe jetzt viele ASP.NET MVC-Anwendungen, in denen sich fast die gesamte Logik in den Controllern befindet. Dies ist ein fehlgeschlagener Versuch, die klassische 3-Schicht-Architektur zu implementieren. Controller sind schwer zu testen, da sie so viele UI-spezifische Probleme haben. In der Tat ist das Schreiben eines Controllers so, dass er nicht direkt mit "HTTP-Kontext" -Werten in Zusammenhang steht, eine ernsthafte Herausforderung an sich. Idealerweise sollte der Controller nur eine Übersetzung durchführen, die Arbeit koordinieren und die Antwort zurückspucken.

Es kann sogar sinnvoll sein, eine grundlegende Validierung in der Anwendungsschicht durchzuführen. Es ist in Ordnung, dass die Domain die darin enthaltenen Werte als sinnvoll ansieht (ist dies eine gültige ID für diesen Kunden und repräsentiert diese Zeichenfolge ein Datum / eine Uhrzeit). Die Validierung mit Geschäftslogik (kann ich in der Vergangenheit ein Flugticket reservieren?) Sollte jedoch für die Domain-Schicht reserviert werden.

Martin Fowler kommentiert tatsächlich, wie flach die meisten Domain-Schichten heutzutage sind . Obwohl die meisten Leute nicht einmal wissen, was eine Anwendungsschicht ist, stellen viele Leute eher dumme Domänenobjekte und komplexe Anwendungsschichten her, die die Arbeit der verschiedenen Domänenobjekte koordinieren. Ich bin selbst schuld daran. Das Wichtigste ist nicht, eine Ebene aufzubauen, weil es Ihnen in einem Buch vorgeschrieben wurde. Die Idee ist, Verantwortlichkeiten zu identifizieren und Ihren Code basierend auf diesen Verantwortlichkeiten zu trennen. In meinem Fall hat sich die "Anwendungsschicht" natürlich weiterentwickelt, als ich die Einheitentests vergrößerte.


9
Ich denke nicht, was Sie hier angeben, ist richtig: "Allerdings muss etwas UI-spezifische Werte (Abfragezeichenfolgen, POST-Daten, Sitzung usw.) in Domänenobjekte übersetzen. Hier kommt die Anwendungsebene ins Spiel". Was Sie meinen, ist in DDDs Begriffen die "Präsentations" -Schicht. Die Anwendungsebene soll sich mit Installationsproblemen, Nebenläufigkeiten und Querschnittsthemen befassen und nur eine winzige Hülle über der Domänenebene sein. Was Sie beschreiben, würde einer (Unter-) Ebene in der Präsentationsebene entsprechen.
verschlang Elysium

23

Aus Martin Fowlers Mustern des Unternehmensdesigns entnommen, sind die häufigsten Ebenen:

  • Präsentation - Dies sind Ansichten, Präsentationsvorlagen, die die Interaktionsschnittstelle für Ihre Anwendung generieren. (Ich verwende die Interaktion, wenn andere Systeme über Webdienste oder RMI auf Ihre Anwendung zugreifen. Dies ist möglicherweise keine Benutzeroberfläche.) Dies schließt auch Controller ein, die entscheiden, wie und wie Aktionen ausgeführt werden.

  • Domain - Hier befinden sich Ihre Geschäftsregeln und - logiken, Ihre Domainmodelle werden definiert usw

  • Datenquelle - Dies ist die Datenzuordnungsschicht (ORM) und die Datenquelle (Datenbank, Dateisystem usw.).

Wie zeichnen Sie die Grenzen zwischen den drei Ebenen:

  • Platzieren Sie keine präsentationsspezifische Logik in Ihren Modellen oder Domänenobjekten

  • Platzieren Sie keine Logik in Ihren Seiten und Controllern, dh keine Logik zum Speichern von Objekten in der Datenbank, zum Erstellen von Datenbankverbindungen usw., wodurch Ihre Präsentationsschicht spröde und schwer zu testen wird

  • Verwenden Sie ein ORM, mit dem Sie den Zugriff auf die Datenquelle und die Aktionen vom Modell entkoppeln können

  • Folgen Sie dem Thin-Controller-Fat-Model-Paradigma. Controller steuern den Ausführungsprozess, ohne ihn auszuführen. Weitere Informationen finden Sie unter http://www.littlehart.net/atthekeyboard/2007/04/27/fat-models-skinny-controllers/ und http://weblog.jamisbuck.org/2006/10/18/skinny-controller-fat-model model, view and controller,


17

Die Domänenschicht modelliert das Geschäft Ihrer Anwendung. Dies sollte Ihre klare Interpretation der Regeln, der Komponentendynamik und des aktuellen Zustands sein.

Die Anwendungsschicht "macht sich Sorgen" um die Definition der Jobs, die zur Ausführung einer bestimmten Anwendungsaufgabe ausgeführt werden müssen. Hauptsächlich ist es für das Mandat der erforderlichen Domainarbeit verantwortlich und interagiert mit anderen (externen oder nicht) Diensten.

Zum Beispiel hat meine Finanzsoftware - Anwendung eine Benutzeroperation für den Zustand eines Modell Einheit zu ändern (Einheit wie in DDD definiert [89]):

  • "Der Einsatzleiter kann einen Finanzierungsvorschlag genehmigen".

Als Antragsprozess muss ich jedoch neben allen Modellfolgen dieses Vorgangs eine interne Mitteilung an andere Benutzer des Antrags senden. Diese Art von Arbeit wird in der Anwendungsebene "orchestriert". Ich möchte nicht, dass meine Domain-Schicht darüber nachdenkt, einen Messaging-Dienst zu leiten. (und dies ist sicherlich keine Verantwortung für die Präsentationsebene). Auf jeden Fall ist eines sicher: Ich brauche eine neue Ebene, da sich meine Domänenebene um das Kerngeschäft und meine Präsentationsebene um die Interpretation von Benutzerbefehlen und die Präsentation von Ergebnissen dreht.

Anmerkungen:

  • Business ist eines dieser Wörter, die häufig zu mehrfachen Interpretationen der Bedeutung führen, aber in DDD finden Sie mit Sicherheit viele Beispiele und Diskussionsbeiträge.
  • DDD steht für Domain-Driven Design Book von Eric Evans und Nummer in eckigen Klammern für Seitenzahl.

6

Die Domänenschicht sollte als Isolationsschicht konzipiert werden. Dies bedeutet, dass die Geschäftslogik und -regeln nicht durch Codeänderungen (in der Anwendungsschicht, der Präsentationsschicht und der Infrastrukturschicht) beeinflusst werden.

Die Anwendungsschicht soll einige Funktionen bereitstellen, die beschreiben, was eine Systemschnittstelle (Anwendungsschnittstelle) (wie eine API oder RESTful) leisten kann. Beispielsweise können sich Benutzer in einem System anmelden. Bei dieser Anwendungsaktion (Anmeldung) sind Anwendungsschichtcodes die Clientcodes für die Domänenschicht (oder Infrastrukturschicht), in der das Benutzerdomänenobjekt abgerufen und die Methoden dieses Objekts angewendet werden, um das zu implementieren 'Login'-Funktion.

Die Anwendungsebene sollte auch als Isolationsebene konzipiert werden. Dies bedeutet, dass das Verhalten der Anwendung durch keine Codeänderungen (in der Präsentationsebene, der Domänenebene und der Infrastrukturebene) beeinflusst werden sollte.


2
Zumindest in der Literatur wie Domain-Driven Design (Evans), wird anerkannt , dass die Schichten eine Einbahn Abhängigkeit ... Tatsache ist, dass an einem gewissen Punkt des Code abhängt etwas . Die Benutzeroberfläche hängt von der Anwendung ab, aber nicht umgekehrt. Die Anwendung ist domänenabhängig, jedoch nicht umgekehrt. Domain on Infrastructure, nicht umgekehrt.

1
Bei der Abhängigkeit geht es darum, wie Sie programmieren, bei der Isolationsebene darum, wie Sie Ihre Systemebenen entwerfen. Eine Einwegabhängigkeit bricht hier nicht das Isolationskonzept, da der Code der obersten Ebene bei der Programmierung eher von der Schnittstelle der unteren Ebene als von den Implementierungsklassen abhängen sollte.
Stevesun21

Das ist großartig und alles auf Papier, aber in der Praxis führen geschäftliche Anforderungen zu Änderungen, die sich auf die Benutzeroberfläche der Anwendungsschicht auswirken können, sodass Änderungen über die Präsentationsschicht und manchmal bis in die Speicherschicht hinein auftreten. Das ist alles, was ich bekommen habe ...

Das Design der Isolationsschicht bedeutet nicht, dass in Zukunft keine Änderungen mehr zulässig sind. Im Gegenteil, es macht die Änderungen viel einfacher - einfacher zu testen und einfacher, die Werke abzuschätzen. Ja, eine neue Geschäftsanforderung bedeutet, dass Sie möglicherweise von oben nach unten wechseln müssen. Ist es nicht die Art und Weise, wie Sie die vorhandene Funktion zuvor implementiert haben? Wenn Sie jede Ebene auf der Grundlage von SOLID-Prinzipien entwerfen können, haben Sie möglicherweise festgestellt, dass Sie vorhandene Funktionen der unteren Ebene einfach wiederverwenden können.
Stevesun21

3

Bei der domänengesteuerten Modellierung geht es darum, das wesentliche Domänenmodell herauszusondern und es ohne Abhängigkeiten von anderen Ebenen und anderen Anwendungsproblemen zu existieren.

Auf diese Weise können Sie sich ohne Ablenkungen auf die Domäne selbst konzentrieren (z. B. die Koordination zwischen der Benutzeroberfläche und den Persistenzdiensten).


Befindet sich die Datenquelle (ein ORM) dann in der Domäne?
Maykonn

@ Maykonn - Es könnte sein. Ein ORM ist jedoch keine Datenquelle. Es ist ein Werkzeug zwischen Ihrem Code und der eigentlichen Datenquelle (einer relationalen Datenbank). Wie Sie auf die Daten zugreifen, sollte kein Problem der Domäne sein - Erbauer und Fabriken können damit umgehen (und ein ORM, falls Sie eines haben).
Oded

Genau. Und ich habe mich in Bezug auf Datenquelle und ORM geirrt. Vielen Dank!
Maykonn

3
  • Die Anwendungsschicht und die Domänenschicht fallen beide in den Implementierungsumfang.
  • Application Layer fungiert als API.
  • Die Domänenschicht fungiert als API-Implementierung und enthält Geschäftslogik. Sie wird daher auch als Geschäftslogikschicht bezeichnet.

Bildbeschreibung hier eingeben


Niemals davon auf diese Weise .... Ich fühle mich erleuchtet
Nikos

2

Der Hauptgrund für diese Grenzen ist die Trennung von Bedenken . Der Code, der auf den Datenspeicher zugreift, muss sich nur um den Zugriff auf den Datenspeicher kümmern. Es sollte nicht dafür verantwortlich sein, Regeln für die Daten durchzusetzen. Darüber hinaus sollte die Benutzeroberfläche dafür verantwortlich sein, die Steuerelemente in der Benutzeroberfläche zu aktualisieren, Werte von Benutzereingaben abzurufen und diese in etwas zu übersetzen, das von der Domänenschicht verwendet werden kann, und nicht mehr. Es sollte Operationen aufrufen, die von der Domänenschicht bereitgestellt werden, um alle erforderlichen Aktionen auszuführen (z. B. diese Datei speichern). Ein aufgerufener Webdienst sollte für die Konvertierung vom Übertragungsmedium in einen Bereich verantwortlich sein, den die Domänenschicht verwenden kann, und dann die Domänenschicht aufrufen (die meisten Tools erledigen einen Großteil dieser Arbeit für Sie).

Wenn diese Trennung richtig implementiert ist, können Sie Teile Ihres Codes ändern, ohne andere zu beeinflussen. Möglicherweise muss die Sortierreihenfolge einer zurückgegebenen Sammlung von Objekten geändert werden. Da Sie wissen, dass die für die Datenmanipulation verantwortliche Schicht (normalerweise die Geschäftslogikschicht) diese Aufgaben übernimmt, können Sie leicht feststellen, wo der Code geändert werden muss. Außerdem müssen Sie nicht ändern, wie es aus dem Datenspeicher oder einer der Anwendungen abgerufen wird, die die Domäne verwenden (die Benutzeroberfläche und der Webdienst aus meinem obigen Beispiel).

Das ultimative Ziel ist es, Ihren Code so einfach wie möglich zu pflegen.

Nebenbei bemerkt, einige Dinge können nicht in eine bestimmte Ebene der Domäne eingeordnet werden (z. B. Protokollierung, Validierung und Autorisierung). Diese Elemente werden im Allgemeinen als Querschnittsthemen bezeichnet und können in einigen Fällen als eigenständige Ebene behandelt werden, die alle anderen Ebenen sehen und verwenden können.

Persönlich denke ich, dass der mehrschichtige Ansatz veraltet ist und dass der Service-Ansatz besser ist. Du hast immer noch die klare Linie im Sand, wer was tut, aber es zwingt dich nicht dazu, so hierarchisch zu sein. Beispielsweise stellen ein Bestellservice, ein Abrechnungsservice und ein Versandservice aus der Anwendungsperspektive alle diese Services Ihre Domain dar, und die oben beschriebene Übertragung der Verantwortung gilt in diesem Zusammenhang noch, sie wurde soeben geändert dass Ihre Domain an mehreren Orten vorhanden ist, wobei das Konzept der Trennung von Interessen weiter genutzt wird.


Ich war neugierig auf die Platzierung der Berechtigungslogik und nach dem, was ich zu verstehen versuche, passt sie in die "Anwendungsschicht". Würde es Ihnen etwas ausmachen, einen Einblick zu geben, warum es möglicherweise nicht am besten ist, ihn in dieser Logikebene zu verbergen?

1
Das ist die perfekte Art von Frage für diese Site. Du solltest es posten, damit jeder eine Chance hat zu antworten.
Charles Lambert

@tuespetre Könnten Sie einen Link zu diesem Beitrag bereitstellen?
Drizzie
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.