2009-04-27 4 views
4

Bevor ich meine "allgemeine" Frage stellen, wollte ich einige Anführungszeichen zu meinem allgemeinen Verständnis der Geschäftsdelegierten Muster zu präsentieren:Generell auf große J2EE-Web-Anwendung, klar Anwendung durch Module zu trennen. Mögliche Verwendung von Geschäftsdelegierten Muster

"Sie möchten Clients von der Komplexität der ausblenden Remote-Kommunikation mit Business-Service-Komponenten. "

"Sie möchten auf die Business-Tier-Komponenten von Ihren Präsentationsschicht-Komponenten und -Clients wie Geräten, Web-Services und Rich-Clients zugreifen."

Nehmen wir an, Sie haben eine große J2EE-Webanwendung. Wenn ich groß meine, meine ich, dass die Anwendung seit mehreren Jahren und von vielen verschiedenen Personen und Abteilungen entwickelt wurde. Das System wurde nicht gut für das Wachstum entwickelt. Nehmen wir an, die Anwendung ist jetzt mit einer Webanwendung konfiguriert.

Es wäre großartig gewesen, wenn die Anwendung modularer wäre. Aber es ist nicht. Ein Code oder eine Bibliothek kann das gesamte System zum Absturz bringen. Testing und andere Mittel werden verwendet, um dies zu verhindern, aber im Idealfall ist dies nur eine monolithische Webanwendung.

Hier ist meine Frage; Wie vermeidet man normalerweise diese Art von Design mit J2EE-Apps, wo die Anwendung wächst und wächst und eine separate Anwendung alles zusammenbringt.

Ich bin nicht vertraut EJBs und planen nicht, sie für etwas zu ernst zu verwenden. Aber das Konzept des Business Delegate und Service Locator Pattern scheint gut zu passen.

Nehmen wir an, Sie haben einen Einkaufswagen-Bildschirm (gleiche Web-App) und eine Reihe von Bildschirmen zum Verwalten eines Benutzerkontos (gleiche Web-App). In Ihrem Web-Tier (irgendeine Art von MVC-Aktionsmethode) scheint es, dass Sie einen Locator haben könnten, der die geschäftsspezifische Schnittstelle bekommt, diese Interfaces pro Modul aufruft und wenn etwas mit dem Modul schief geht, dann tötet es keinen anderen Code . Nehmen wir an, das Warenkorbmodul schlägt fehl (aus welchen Gründen auch immer), der Benutzerkontenbildschirm funktioniert immer noch.


+0

Was passiert, wenn ein Code das gesamte System zum Absturz bringt? Stürzen Sie Ihre Datenbank ab, da nicht genügend Arbeitsspeicher zur Verfügung steht und die gemeinsamen Daten beschädigt werden? – Ichorus

Antwort

1

In einem gesunden Software-Entwicklungsumgebung, die Anwendung „wächst und wächst“, weil bussiness Leute für Änderungen und neue Features stellen und in der Regel gibt es nichts zu beanstanden.

Lassen Sie uns über die Skalierbarkeit Problem vergessen, und konzentrieren sich auf das Design-Problem, mit führt zu einer sehr schmerzhaften Wartung.

Was Sie tun müssen, ist Ihre Anwendung in Modulen zu trennen, die für die Geschäftsleute (und die Benutzer) sinnvoll ist. Jedes Modul Ihres Systems sollte ein klares Geschäftsmittel haben, das die Anwendungsdomäne widerspiegelt.

1

All diese Ideen sind in Ordnung, und wäre völlig in Ordnung, wenn Sie bei Null anfangen würden. Leider fangen Sie nicht bei Null an, sondern beschäftigen sich mit einem prototypischen Big Ball of Mud. Glaub mir, wenn ich sage, dass ich deinen Schmerz fühle.

Wichtiger als das spezifische Muster ist es, irgendeine Art von Ordnung, irgendeine Art von Ordnung, auf diesem Chaos anzuordnen. Wichtiger als Ihre spezifische Design-Wahl - können Sie Ihre Design-Entscheidung reaktiv auf das gesamte System übertragen, so dass es ein einheitliches Paradigma gibt, das die gesamte Anwendung durchzieht?

Wenn Ihr Design die Designanforderungen erfüllt und die Anwendung konzeptionell vereinfacht, ist es gültig.

1

Der beste Weg, ein System wie dieses zu verbessern, ist, es langsam besser zu machen. Wenn Ihr System den Systemen entspricht, an denen ich gearbeitet habe, führt das Ändern des Codes oft zu Fehlern. Automatisierte Tests sind eine Möglichkeit, die Wahrscheinlichkeit neuer Bugs zu reduzieren. Häufig wurde der Code jedoch nicht mit Tests erstellt, und das Ändern des Codes, um das Schreiben von Tests zu erleichtern, kann zu Fehlern führen.

Um dieses Problem zu lösen, führen Sie einige automatisierte Integrationstests ein und verwenden Sie diese Tests als Sicherheitsnetz, da Sie den Code sorgfältig umgestalten und Tests auf einer niedrigeren Ebene einführen. Wenn Sie Code testbarer machen, werden häufig Schnittstellen und Abstraktionen eingeführt, die die Arbeit mit dem Code erleichtern. Es erfordert oft auch, die Geschäftslogik von der Präsentationslogik zu trennen (da das Testen beider zusammen schmerzhaft ist) und unseren Code in Module zu zerlegen (da Klassen mit vielen Abhängigkeiten schwer zu testen sind).

Wenn Sie neuen Code für Ihr System schreiben, versuchen Sie Komponententests zu schreiben, während Sie den Code schreiben. Dies ist viel einfacher (und daher weniger frustrierend) als das Schreiben von Tests für Legacy-Code und gibt Ihnen die Möglichkeit zu sehen, wohin Sie gehen könnten, wenn Sie Ihren Legacy-Code umgestalten.

Ich kenne zwei ausgezeichnete Bugs zu diesem Thema: Working Effectively with Legacy Code von Robert C. Martin und Refactoring to Patterns von Joshua Kerievsky.

Betrachten Sie schließlich die Verwendung eines Abhängigkeitsinjektions-Frameworks wie Spring oder Guice. Die Abhängigkeitseinspeisung macht es einfacher, Ihren Code mit Komponententests testbar zu machen. Es erleichtert auch die Einhaltung guter Konstruktionspraktiken wie und Interface Segregation Principle.

1

Der beste Weg, so ein Durcheinander zu vermeiden, wenn Sie eine Chance gegeben wurden neu zu starten ist:

  • das Spring Framework verwenden im gesamten Gebäude.
  • Achten Sie auf hohe Kohäsion, geringe Kopplung: Stellen Sie sicher, dass es keine zirkulären Abhängigkeiten zwischen den Paketen gibt (com.myapp.packageA hängt von com.myapp.packageB ab, das von com.myapp.packageA abhängt). Es gibt einige großartige kostenlose Tools wie Architekturregeln, die das für Sie automatisch überprüfen können.

Mit diesen beiden Regeln werden Sie bereits gezwungen sein, solide gute Designprinzipien zu befolgen. Ansonsten muss Design ständig beachtet werden. Der Sinn jedes Konstruktionsaufwands besteht darin, die Unsicherheit zu reduzieren, sodass Sie im Grunde wissen müssen, warum Sie überhaupt konstruieren.