Java >> Java Tutorial >  >> Tag >> Spring

Die Architektur von Spring-Webanwendungen verstehen:Der klassische Weg

Jeder Entwickler muss zwei Dinge verstehen:

  1. Architekturdesign ist notwendig.
  2. Ausgefallene Architekturdiagramme beschreiben nicht die wirkliche Architektur einer Anwendung.

Die wirkliche Architektur ergibt sich aus dem von Entwicklern geschriebenen Code, und wenn wir die Architektur unserer Anwendung nicht entwerfen, werden wir am Ende eine Anwendung mit mehr als einer Architektur haben.

Bedeutet das, dass Entwickler von Architekten regiert werden sollten?

Nein . Architekturdesign ist viel zu wichtig, um es den Architekten zu überlassen, und deshalb jedem Entwickler , der mehr als nur Schreibmaschine sein will, muss gut darin sein .

Beginnen wir unsere Reise mit einem Blick auf die beiden Prinzipien, die uns helfen werden, eine bessere und einfachere Architektur für unsere Spring-unterstützte Webanwendung zu entwerfen.

Die zwei Säulen einer guten Architektur

Architekturdesign kann sich wie eine überwältigende Aufgabe anfühlen. Der Grund dafür ist, dass vielen Entwicklern beigebracht wird zu glauben, dass Architekturdesign von Menschen gemacht werden muss, die Hüter einer mystischen Weisheit sind. Diese Leute werden Softwarearchitekten genannt.

Die Aufgabe selbst ist jedoch nicht so kompliziert, wie es sich anhört:

Softwarearchitektur ist die übergeordnete Struktur eines Softwaresystems, die Disziplin der Erstellung einer solchen übergeordneten Struktur und die Dokumentation dieser Struktur.

Obwohl es stimmt, dass Erfahrung uns hilft, bessere Architekturen zu erstellen, sind die grundlegenden Werkzeuge eines Architekturentwurfs eigentlich recht einfach. Alles, was wir tun müssen, ist, diese beiden Prinzipien zu befolgen:

1. Das Prinzip der Unternehmenstrennung (SoC)

Das Separation of Concerns (SoC)-Prinzip wird wie folgt konkretisiert:

Separation of Concerns (SoC) ist ein Entwurfsprinzip, um ein Computerprogramm in verschiedene Abschnitte zu unterteilen, sodass jeder Abschnitt ein separates Anliegen behandelt.

Das heißt, wir sollten

  1. Identifizieren Sie die "Bedenken", um die wir uns kümmern müssen.
  2. Entscheiden Sie, wo wir sie handhaben wollen.

Mit anderen Worten, dieses Prinzip hilft uns, die erforderlichen Ebenen und die Verantwortlichkeiten jeder Ebene zu identifizieren.

2. Das Keep It Simple Stupid (KISS)-Prinzip

Das Keep It Simple Stupid (KISS)-Prinzip besagt:

Die meisten Systeme funktionieren am besten, wenn sie einfach gehalten und nicht kompliziert gemacht werden; Daher sollte Einfachheit ein Hauptziel beim Design sein und unnötige Komplexität sollte vermieden werden.

Dieses Prinzip ist die Stimme der Vernunft. Es erinnert uns daran, dass jede Ebene einen Preis hat, und wenn wir eine komplexe Architektur mit zu vielen Ebenen erstellen, wird dieser Preis zu hoch sein.

Mit anderen Worten, wir sollten eine solche Architektur nicht entwerfen :

Quelle:Geek And Poke:Footprints – Lizenziert unter CC 3.0

Ich denke, dass John, Judy, Marc und David der geistigen Masturbation schuldig sind . Sie folgten dem Prinzip der Trennung von Anliegen, vergaßen jedoch, die Komplexität ihrer Architektur zu minimieren. Leider ist dies ein häufiger Fehler, und sein Preis ist hoch:

  1. Das Hinzufügen neuer Funktionen dauert viel länger, als es sollte, da wir Informationen durch jede Ebene übertragen müssen.
  2. Die Wartung der Anwendung ist unmöglich, weil niemand die Architektur wirklich versteht, und die Ad-hoc-Entscheidungen, die alle getroffen werden, häufen sich an, bis unsere Codebasis wie ein großer Scheißhaufen mit zehn Schichten aussieht .

Dies wirft eine offensichtliche Frage auf:

Welche Art von Architektur könnte uns gute Dienste leisten?

Drei Schichten sollten für alle ausreichen

Wenn Sie über die Verantwortlichkeiten einer Webanwendung nachdenken, stellen wir fest, dass eine Webanwendung die folgenden "Bedenken" hat:

  • Es muss die Eingabe des Benutzers verarbeiten und die richtige Antwort an den Benutzer zurücksenden.
  • Es braucht einen Ausnahmebehandlungsmechanismus, der dem Benutzer vernünftige Fehlermeldungen liefert.
  • Es braucht eine Transaktionsmanagementstrategie.
  • Es muss sowohl die Authentifizierung als auch die Autorisierung handhaben.
  • Es muss die Geschäftslogik der Anwendung implementieren.
  • Es muss mit dem verwendeten Datenspeicher und anderen externen Ressourcen kommunizieren.

All diese Anliegen können wir erfüllen, indem wir „nur“ drei Schichten verwenden. Diese Ebenen sind:

  • Die Webebene ist die oberste Schicht einer Webanwendung. Es ist dafür verantwortlich, die Eingaben des Benutzers zu verarbeiten und die richtige Antwort an den Benutzer zurückzusenden. Der Web-Layer muss auch die von den anderen Layern ausgelösten Ausnahmen behandeln. Da die Webschicht der Einstiegspunkt unserer Anwendung ist, muss sie sich um die Authentifizierung kümmern und als erste Verteidigungslinie gegen unbefugte Benutzer fungieren.
  • Die Dienstschicht befindet sich unterhalb der Webschicht. Es fungiert als Transaktionsgrenze und enthält sowohl Anwendungs- als auch Infrastrukturdienste. Die Anwendungsdienste stellt die öffentliche API der Serviceschicht bereit. Sie fungieren auch als Transaktionsgrenze und sind für die Autorisierung verantwortlich. Die Infrastrukturdienste enthalten den „Installationscode“, der mit externen Ressourcen wie Dateisystemen, Datenbanken oder E-Mail-Servern kommuniziert. Häufig werden diese Methoden von mehr als einem Anwendungsdienst verwendet.
  • Die Repository-Schicht ist die unterste Schicht einer Webanwendung. Es ist für die Kommunikation mit dem verwendeten Datenspeicher verantwortlich.

Die High-Level-Architektur einer klassischen Spring-Webanwendung sieht wie folgt aus:

Als nächstes müssen wir die Schnittstelle jeder Schicht entwerfen, und das ist die Phase, in der wir auf Begriffe wie Data Transfer Object (DTO) und Domänenmodell stoßen. Diese Begriffe werden im Folgenden beschrieben:

  • Ein Datenübertragungsobjekt ist ein Objekt, das nur ein einfacher Datencontainer ist, und diese Objekte werden verwendet, um Daten zwischen verschiedenen Prozessen und zwischen den Schichten unserer Anwendung zu transportieren.
  • Ein Domänenmodell besteht aus drei verschiedenen Objekten:
    • Ein Domain-Dienst ist eine zustandslose Klasse, die Operationen bereitstellt, die sich auf ein Domänenkonzept beziehen, aber kein „natürlicher“ Teil einer Entität oder eines Wertobjekts sind.
    • Eine Entität ist ein Objekt, das durch seine Identität definiert ist, die während seines gesamten Lebenszyklus unverändert bleibt.
    • Ein Wertobjekt beschreibt eine Eigenschaft oder ein Ding, und diese Objekte haben keine eigene Identität oder einen eigenen Lebenszyklus. Der Lebenszyklus eines Wertobjekts ist an den Lebenszyklus einer Entität gebunden.

Jetzt, da wir wissen, was diese Begriffe bedeuten, können wir weitermachen und die Schnittstelle jeder Ebene entwerfen. Gehen wir unsere Ebenen nacheinander durch:

  • Der Web-Layer sollte nur Datenübertragungsobjekte verarbeiten.
  • Die Serviceschicht nimmt Datenübertragungsobjekte (und Basistypen) als Methodenparameter. Es kann Domänenmodellobjekte verarbeiten, aber nur Datenübertragungsobjekte an die Webschicht zurückgeben.
  • Die Repository-Schicht nimmt Entitäten (und Basistypen) als Methodenparameter und gibt Entitäten (und Basistypen) zurück.

Dies wirft eine sehr wichtige Frage auf:

Brauchen wir wirklich Datenübertragungsobjekte? Warum können wir Entitäten und Wertobjekte nicht einfach an die Webschicht zurückgeben?

Es gibt zwei Gründe, warum dies eine schlechte Idee ist:

  1. Das Domänenmodell spezifiziert das interne Modell unserer Anwendung. Wenn wir dieses Modell nach außen tragen, müssten die Kunden wissen, wie man es benutzt. Mit anderen Worten, die Clients unserer Anwendung müssten sich um Dinge kümmern, die ihnen nicht gehören. Wenn wir DTOs verwenden, können wir dieses Modell vor den Clients unserer Anwendung verbergen und eine einfachere und sauberere API bereitstellen.
  2. Wenn wir unser Domänenmodell der Außenwelt aussetzen, können wir es nicht ändern, ohne die anderen davon abhängigen Dinge zu beschädigen. Wenn wir DTOs verwenden, können wir unser Domänenmodell ändern, solange wir keine Änderungen an den DTOs vornehmen.

Die "endgültige" Architektur einer klassischen Spring-Webanwendung sieht wie folgt aus:

Es gibt noch viele unbeantwortete Fragen

Dieser Blogbeitrag beschreibt die klassische Architektur einer Spring-Webanwendung, gibt aber keine Antworten auf die wirklich interessanten Fragen wie:

  • Warum ist die Schicht X für das Anliegen Y zuständig?
  • Sollte unsere Anwendung mehr als drei oder weniger als drei Schichten haben?
  • Wie sollten wir die interne Struktur jeder Schicht gestalten?
  • Brauchen wir wirklich Schichten?

Der Grund dafür ist einfach:

Wir müssen laufen lernen, bevor wir laufen können .

Die nächsten Blogbeiträge dieses Tutorials werden diese Fragen beantworten.


Java-Tag