Entwurfsmuster sorgen für bessere J2EE-Apps

Seit seiner Einführung hat J2EE (Java 2 Platform, Enterprise Edition) die Erstellung von Unternehmensanwendungen in Java vereinfacht. Mit zunehmender Verbreitung von J2EE erkennen die Entwickler jedoch die Notwendigkeit definierter Ansätze, die die Anwendungserstellung sowohl vereinfachen als auch standardisieren. Sie können dieses Ziel erreichen, indem Sie die Architekturebene Ihrer Anwendung standardisieren .

Die Architekturschicht kapselt im Allgemeinen die technischen Komplexitäten einer Anwendung unabhängig von der Geschäftslogik und bietet so eine lose Kopplung zwischen der Geschäftsfunktionalität und der zugrunde liegenden technischen Infrastruktur. In diesem Artikel erkläre ich eine neue Methode zum Erstellen der Anwendungsarchitektur für J2EE-Projekte, bei der Entwurfsmuster verwendet werden, um die Standardisierung und Einfachheit bereitzustellen, die eine gute Architektur erfordert.

Anwendungsarchitektur und J2EE

J2EE ist eine großartige Infrastrukturtechnologie. Es bietet einen einheitlichen Standard für die untergeordneten Aufgaben des Technologie-Stacks, wie z. B. Datenbankkommunikation oder Anwendungsverteilung. J2EE führt Entwickler jedoch nicht dazu, erfolgreiche Anwendungen zu erstellen. Die Entwickler von J2EE, die in den Technologie-Stack blickten, fragten sich: "Wie können wir diese APIs standardisieren?" Sie hätten zu den Anwendungsentwicklern aufblicken und fragen sollen: "Wie kann ich Entwicklern die Bausteine ​​geben, die sie benötigen, um sich auf ihre Geschäftsanwendung zu konzentrieren?"

Zu Beginn eines neuen J2EE-Projekts fragen einige Teammitglieder häufig: "Wenn J2EE selbst eine Architektur ist, warum brauchen wir mehr?" Viele Entwickler hielten dieses Missverständnis in den Anfängen von J2EE, aber erfahrene J2EE-Entwickler wissen, dass J2EE nicht die Anwendungsarchitektur bereitstellt, die für die konsistente Bereitstellung qualitativ hochwertiger Anwendungen erforderlich ist. Diese Entwickler verwenden häufig Entwurfsmuster, um diese Lücke zu schließen.

Designmuster

Bei der Programmierung können Sie mithilfe von Entwurfsmustern die kollektive Erfahrung der Entwicklergemeinschaft nutzen, indem Sie Probleme und Lösungen austauschen, von denen alle profitieren. Ein Entwurfsmuster muss die Definition und den Kontext eines Problems, eine mögliche Lösung und die Konsequenzen der Lösung erfassen.

Für die Zwecke der J2EE-Anwendungsarchitektur lassen sich Entwurfsmuster in zwei Kategorien einteilen: allgemeine Softwareentwicklungsmuster und Muster, die bestimmte J2EE-Herausforderungen identifizieren. J2EE-spezifische Entwurfsmuster identifizieren den minimalen Satz bekannter Probleme, die eine solide Anwendungsarchitektur lösen sollte. Die erstere Gruppe, die Softwareentwicklungsmuster, die nicht spezifisch für J2EE sind, erweist sich als ebenso leistungsfähig - nicht zur Identifizierung von Problemen, sondern zur Steuerung der Architekturkonstruktion.

Lassen Sie uns jeden Bereich genauer untersuchen.

J2EE-Entwurfsmuster

J2EE-Entwurfsmuster haben sich in den letzten Jahren weiterentwickelt, da die Java-Community J2EE-Erfahrung gesammelt hat. Diese Entwurfsmuster identifizieren potenzielle Probleme, die bei der Verwendung der verschiedenen J2EE-spezifizierten Technologien auftreten, und helfen Entwicklern beim Erstellen der Anforderungen einer Anwendungsarchitektur. Das beliebte Front Controller-Entwurfsmuster verwandelt beispielsweise unstrukturierten Servlet-Code in einen Controller, der an die verfeinerte Entwicklung der grafischen Benutzeroberfläche (grafische Benutzeroberfläche) erinnert.

J2EE-Entwurfsmuster identifizieren die Domänenprobleme, die am wahrscheinlichsten in Ihren J2EE-Projekten auftreten. Wenn die Probleme selten wären, hätten sich die Entwurfsmuster nicht entwickelt, um sie zu erfüllen. In diesem Sinne profitieren Sie von der Lösung jedes Domänenproblems in Ihrer Architektur. Um sie alle zu lösen, erstellen Sie eine Checkliste, um Ihre Architektur auf Vollständigkeit zu überprüfen. Dieser Prozess steht im Gegensatz zu dem Prozess für die Softwareentwicklungs-Entwurfsmuster, die ich als Nächstes diskutiere, da Sie diese Muster nur dann anwenden müssen, wenn und falls dies angebracht ist.

Wo finden Sie J2EE-Designmuster? Sun Microsystems bietet zwei Bücher an, die viele J2EE-Muster enthalten:

  • Das Entwerfen von Unternehmensanwendungen der J2EE BluePrint Group mit der Java 2-Plattform (Enterprise Edition), Nicholas Kassem et al. (Addison-Wesley, 2000; ISBN: 0201702770)
  • Die wichtigsten J2EE-Muster der Sun Professional Services Group : Best Practices und Designstrategien, Deepak Alur, John Crupi und Dan Malks (Prentice Hall, 2001; ISBN: 0130648841)

(Links zu beiden Büchern finden Sie unter Ressourcen.)

Über die Ressourcen von Sun hinaus bieten andere Veröffentlichungen Informationen zu J2EE-Entwurfsmustern, darunter verschiedene Java-Branchenmagazine oder Websites (wie JavaWorld ) sowie zahlreiche Bücher. (Siehe Ressourcen für Links zu einigen dieser Seiten, einschließlich Javaworld‘ s Design Patterns Topical Index - Seite.)

Entwurfsmuster für die Softwareentwicklung

Beachten Sie auch die Entwurfsmuster für die Softwareentwicklung, die in allgemeine objektorientierte Entwurfsmuster (OO) und Java-spezifische Entwurfsmuster unterteilt sind. Das Factory-Muster stellt beispielsweise ein leistungsstarkes OO-Entwurfsmuster zum Einkapseln der Objekterstellung dar, um die Wiederverwendung zu ermöglichen und die sich ändernden Anforderungen eines Systems zu erfüllen. Java-sprachige Entwurfsmuster berücksichtigen ihrerseits die Besonderheiten der Java-Sprache. Einige sind nur in Java verfügbar und normalerweise informell (z. B. Ausnahmen und Grundelemente), während andere OO-Muster sind, die für die Anwendung auf Java verfeinert wurden. Das berühmte Gang of Four-Buch Design Patterns von Eric Gamma et al. Beschreibt zahlreiche allgemeine Softwareentwicklungsmuster, die für alle Programmierer nützlich sind.

Entlassen Sie diese Muster nicht einfach, weil sie nicht J2EE-spezifisch sind. Im Gegenteil, solche Muster können sich als genauso leistungsfähig erweisen, wenn nicht sogar stärker als J2EE-Entwurfsmuster, weil:

  • Während die J2EE-Entwurfsmuster neu sind und sich weiterentwickeln (weil J2EE neu ist und sich weiterentwickelt), profitieren die anderen Muster vom Alter, da die Branche mehr Zeit hatte, sie zu überprüfen und zu verfeinern.
  • Sie dienen häufig als Grundlage für die J2EE-Entwurfsmuster.
  • Sie bilden die Grundlage für die Implementierung der J2EE-spezifischen Lösungen. Die korrekte Konstruktion dieses Fundaments wirkt sich weitgehend auf die Robustheit und Erweiterbarkeit der gesamten Architektur aus. Bei nicht korrekter Konstruktion würde das Fundament den Nutzen der Architektur minimieren, unabhängig davon, wie viele J2EE-Probleme es löst.

Erstellen Sie keine Checkliste mit den Softwareentwicklungsmustern, die Ihre Architektur benötigt, wie dies bei den J2EE-Mustern der Fall wäre. Verwenden Sie stattdessen gegebenenfalls solche Muster, die auf den spezifischen Herausforderungen Ihres Projekts basieren. Viele Entwickler glauben fälschlicherweise, dass sich ihre Produkte verbessern werden, wenn sie mehr Muster verwenden - oder wenn sie alle verwenden! Dies ist jedoch nicht der Fall. Verwenden Sie Diskretion und Finesse, wenn Sie entscheiden, welche Muster verwendet und wie sie zusammen verwendet werden sollen.

Entwurfsmuster: Wo ist der Code?

Beachten Sie, dass Entwurfsmuster nicht mit der genauen Implementierung oder dem Quellcode geliefert werden, den Sie verwenden werden. Das Angebot an Entwurfsmustern reicht von spärlichen Textbeschreibungen über umfangreiche Dokumentationen bis hin zu möglicherweise Beispielcode. Die Herausforderung besteht darin, die kraftvollen Ideen der Muster anzuwenden. Diese Ideen müssen auf die Umgebung angewendet werden, in der sie verwendet werden. Die Umgebung definiert die richtige Implementierung.

Betrachten Sie als Analogie ein Entwurfsmuster für den Bau eines Hausfundaments. Das Entwurfsmuster identifiziert das Problem, den Kontext und die mögliche Lösung für den Bau des Fundaments - Informationen, die für den Bauarbeiter vor Ort immens wertvoll sind. Der Arbeiter muss jedoch noch das Fundament bauen. Würde dieser Bauarbeiter nicht mehr davon profitieren, wenn ihm die Grundlage gegeben würde (ähnlich wie dem Softwareentwickler, der die Implementierung erhält)? Vielleicht wäre dieses Fundament nur eine Betonplatte, auf der das Haus gebaut werden könnte. Das Problem: Das Fundament muss sich in das Haus selbst und das Land, in dem das Haus wohnen wird, integrieren. Wie kann ein solches vorgefertigtes Fundament alle möglichen Grundrisse des Hauses (Rechteck, Quadrat und andere seltsame Formen) und alle möglichen Landschaften (auf einem Hügel) aufnehmen?mitten im Wald und so weiter)?

Zurück in der Software-Welt hängt die Machbarkeit der Verwendung vorgefertigter Entwurfsmuster von zwei Faktoren ab:

  • Die Implementierung, nicht einzelne Entwurfsmuster, stellt eine Lösung dar. Die Lösung könnte mehrere Entwurfsmuster enthalten und dabei wissen, wie die einzelnen Entwurfsmuster zusammenspielen.
  • Die Lösung muss anpassungsfähig sein, was die letzte Frage aus der Analogie des vorgefertigten Fundaments beantwortet: Das Fundament muss sich an das Gelände und die Grundrisse anpassen können. Wie Sie sich vorstellen können, würde es einen äußerst erfahrenen Handwerker erfordern, um das anpassungsfähige Fundament im Gegensatz zum Standardfundament zu bauen.

Gemeinsame Entwurfsmuster

In der folgenden Tabelle sind einige gängige Entwurfsmuster sowohl aus J2EE-Quellen als auch aus breiteren OO-Mustern aufgeführt.

Gemeinsame Entwurfsmuster
J2EE-Entwurfsmuster Softwareentwicklungsmuster
Sitzungsfassade Singleton
Value Object Assembler Brücke
Service Locator-Muster Prototyp
Geschäftsdelegierter Abstrakte Fabrik
Zusammengesetzte Einheit Fliegengewicht
Wertelisten-Handler Vermittler
Service Locator Strategie
Zusammengesetzte Einheit Dekorateur
Wertobjekt Zustand
Service für den Arbeiter Iterator
Datenzugriffsobjekt Verantwortungskette
Filter abfangen Model View Controller II
Helfer anzeigen Erinnerung
Zusammengesetzte Ansicht Baumeister
Dispatcher-Ansicht Fabrikmethode

Schauen wir uns zwei Beispiele für J2EE-Entwurfsmuster an: die Muster für Sitzungsfassade und Wertobjekt. Beide zeigen, wie sich J2EE-Entwurfsmuster auf Probleme konzentrieren, die speziell für die J2EE-Umgebung gelten, im Gegensatz zu den Entwurfsmustern für die Softwareentwicklung, die im Allgemeinen für alle Anwendungsentwicklungsbemühungen gelten.

Beispiel: Das J2EE-Muster für die Sitzungsfassade

Das Session Facade-Muster entwickelte sich aus Erfahrungen mit Enterprise JavaBeans (EJBs). Systeme, die auf den neu eingeführten Entity-EJBs (die mit einer Datenbank kommunizieren) basieren, wurden langsamer. Leistungstests ergaben Probleme, die sich aus mehreren Netzwerkanrufen bei der Kommunikation mit den EJBs der Entität ergaben. Dies führte zu einem zusätzlichen Aufwand für den Aufbau der Netzwerkverbindung, die Serialisierung der Daten für das Senden und Empfangen sowie für andere Effekte.

Als Reaktion darauf verbesserte das Session Facade-Muster die Leistung, indem diese mehreren Netzwerktreffer in einem einzigen Anruf zusammengefasst wurden. Session Facade verwendet eine zustandslose Sitzungs-EJB, um zwischen dem Client-Aufruf und der erforderlichen EJB-Interaktion der Entität zu vermitteln. Es gibt weitere Muster zur Verbesserung der Datenbankzugriffsleistung, einschließlich der Muster Fast Lane Reader und Data Access Object.

Beispiel: Das Value Object J2EE-Muster

Das Value Object J2EE-Muster zielt auch darauf ab, die Leistung von Systemen zu verbessern, die EJBs über das Netzwerk verwenden. Diese Overhead-induzierenden Netzwerkaufrufe aus dem vorherigen Beispiel rufen einzelne Datenfelder ab. Zum Beispiel können Sie eine haben PersonEntity EJB mit Methoden wie getFirstName(), getMiddleName()und getLastName(). Mit dem Entwurfsmuster "Wertobjekt" können Sie solche mehreren Netzwerkaufrufe mit einer Methode für die Entität EJB auf einen einzigen Aufruf reduzieren, z. B. getPersonValueObject()die Daten auf einmal zurückgibt. Dieses Wertobjekt enthält die Daten, die die Entität EJB darstellt, und kann bei Bedarf aufgerufen werden, ohne dass der Netzwerkaufruf-Overhead entsteht.

Beispiel: Das Flyweight OO-Muster

Betrachten Sie als Beispiel für ein allgemein anwendbares OO-Entwurfsmuster das Flyweight-Muster, das die Anwendungsleistung durch Wiederverwendung von Objekten verbessert. OO-Software verursacht Overhead - verschwendete CPU-Zyklen, Speicherbereinigung und Speicherzuweisung -, wenn sie ein Objekt erstellt und zerstört. Wenn das System diese Objekte wiederverwenden könnte, könnten Sie diesen Overhead vermeiden. Die Objekte sind jedoch häufig nicht wiederverwendbar, da sie Informationen ( Status genannt ) enthalten, die für den aktuellen Benutzer des Objekts spezifisch sind. Das Flyweight-Muster bietet Ansätze zum Verschieben dieses Zustands an eine andere Stelle, damit der Rest des Objekts wiederverwendet werden kann.

Setzen Sie sie alle zusammen: Persistenzbeispiel

Nachdem Sie die Grundlagen kennen, können Sie Entwurfsmuster in Ihren Entwicklungspraktiken anwenden. Aber wie benutzt man eigentlich Muster? Identifizieren Sie zunächst eine Domäne oder ein technisches Problem, für das eine Lösung erforderlich ist. Die Persistenz - das Beheben der jahrhundertealten Nichtübereinstimmung zwischen Objekt und relationaler Datenbank - ist ein gutes Beispiel für die meisten Unternehmensanwendungen. Sehen wir uns die Schritte an, die zum Entwerfen und Erstellen der Persistenzschicht einer Anwendungsarchitektur erforderlich sind.

Erstellen Sie nach dem traditionellen OO-Architektur- und Designansatz Anwendungsfälle, in denen Ihre Persistenzanforderungen beschrieben werden. Mögliche Anwendungsfälle sind:

  1. Die Objektpersistenz sollte aus Sicht der Entwickler transparent sein.
  2. Persistenzmechanismen - Entitäts-EJBs, Datenzugriffsobjekte usw. - sollten auf architektonischer Ebene konfigurierbar sein.
  3. Unsere Architektur sollte J2EE-Technologien verwenden, aber J2EE-Abhängigkeiten kapseln. Wir sollten in der Lage sein, die Anbieter von J2EE-Anwendungsservern und J2EE-Versionen zu ändern oder J2EE vollständig zu ersetzen, ohne dass eine vollständige Anwendungsüberholung erforderlich ist.
  4. Die resultierende Persistenzschicht sollte projektübergreifend wiederverwendbar sein. Dies sollte Teil unserer laufenden Anwendungsarchitektur sein.

Sobald Sie das Problem identifiziert haben, können Sie entscheiden, welche Muster angewendet werden sollen. Denken Sie daran, dass Sie für die J2EE-Muster bestimmen sollten, welche Muster im Problembereich gelten, und diese ansprechen sollten. Für die Persistenz sind die relevanten J2EE-Entwurfsmuster (siehe die J2EE-Entwurfsmusterbücher von Sun in Ressourcen):

  • Wertobjekt
  • Fast Lane Reader
  • Datenzugriffsobjekt
  • Sitzungsfassade
  • Zusammengesetzte Einheit
  • Wertelisten-Handler

Da Sie EJBs verwenden, geben Sie die Muster für Business Delegate und Service Locator an, um den EJB-Zugriff zu adressieren.

Darüber hinaus erfordert die Lösung des zweiten und dritten Anwendungsfalls traditionelle Entwurfsmuster für die Softwareentwicklung. Wie kapseln Sie Abhängigkeiten und haben konfigurierbare Persistenzmechanismen? Einige anwendbare Softwareentwicklungsmuster umfassen:

  • Fabrik
  • Vermittler
  • Strategie