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.
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,
quelle
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]):
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:
quelle
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.
quelle
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).
quelle
quelle
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.
quelle