2010-02-24 4 views
8

Ich bin auf der Suche nach einem Artikel oder Tutorial, das ein Beispiel dafür gibt, wie ein aktuelles MVC-Muster (2.0?) Mit dem Swing-Framework aussehen sollte.Aktuell Swing MVC Beispiel + Frage

Da ich mehr an eine mehrschichtige Architektur gewöhnt bin, würde ich gerne wissen, wie die Domain-Objekte oder POJOs in das Bild passen. Habe ich recht, wenn ich davon ausgehe, dass sie getrennt sind und vom Modell genannt werden? Gibt es hinsichtlich des Musters selbst weit verbreitete Konventionen hinsichtlich der Gruppierung von Klassen in Pakete?

TIA,

James P.

Antwort

26

Das ist eine große Frage ist. Ich werde einige Gedanken mit dir teilen Ich habe zu diesem Thema und sehe, was daraus entsteht.

Swing ist mehr Modell-> Ansicht als Modell-> Ansicht-> Controller. Das Problem mit Model-> View besteht darin, dass Swing-Anwendungen normalerweise ein View-Objekt ableiten und dass Objekte sowohl zum View als auch zum Controller für diese Ansicht werden. Überstunden in großen Anwendungen führt dies zu vielen Problemen und Spaghetti-Code.

Seit einigen Jahren mache ich jetzt ein separates Objekt namens Controller, das keine UI-Klassen erweitert. Es ist ein einfaches altes Objekt in dieser Hinsicht. Dieser Controller wird die Komponenten der obersten Ebene für die Ansicht instanziieren, Hörer mit der Ansicht verbinden, um auf den Benutzer zu reagieren, und umkehren und Anrufe an das Modell senden, um Arbeit zu leisten.

Die Ansicht wird Unterklasse Swing. Die Ansicht ist verantwortlich für das Reagieren auf Mausereignisse, Tastaturereignisse usw. Jede Art von Swing-spezifischem Ereignis wird in der Ansicht behandelt. Es bietet auch Methoden auf hoher Ebene zum Aktualisieren der Ansicht, die der Controller zum Rückruf verwendet, um die Benutzeroberfläche zu aktualisieren. Klassische Swing-Modelle sind ebenfalls Teil des View, da die Auswahl der Komponenten sehr stark an die Modelle gebunden ist, die Sie verwenden. Der View ist auch dafür verantwortlich, Events auf hoher Ebene an den Controller zu senden, und der Controller ist dafür verantwortlich, auf diese Events auf hoher Ebene zu reagieren. Diese Ereignisse können UserEvent.ADD, UserEvent.EDIT, AuthenticationEvent.LOG_IN, AuthenticationEvent.LOG_OUT usw. sein. Bei diesen Ereignissen handelt es sich um Anwendungsereignisse, und sie ähneln mehr dem, was ein Produktmanager möglicherweise erkennt. Der Controller reagiert nicht auf Maus, ChangListener usw. Ich habe tatsächlich ein eigenes EventDispatch- und Event-Framework für diese erstellt, da Swing's so schwer zu erweitern und effektiv zu verwenden ist. Die Ansicht funktioniert so ähnlich:

In meinem Controller habe ich einfache Methoden, die mit diesen Ereignissen verbunden sind. Hier könnte ein Beispiel sein:

@EventCallback(command = "exit") 
public void exit(AppEvent evt) { 
    onExit(); 
} 

@EventCallback(command = "help.about") 
public void showAbout(AppEvent evt) { 
    audioFinderFrame.showAboutDialog(engine.getLicenseInfo()); 
} 

@EventCallback(command = MediaSourceEvent.START_REFRESH) 
public void refreshStarted(final MediaSourceEvent event) { 
    if(frame != null) frame.refreshMediaSource(event.getSource(), true); 
} 

Die Anmerkungen sind eine Erweiterung muss ich Ereignis-Listener-Methoden schnell zu einer EventDisptach Quelle hinzuzufügen. Aber der Punkt ist, dass jede Methode auf dem Controller aus der Ansicht aufgerufen wird, die Ereignisse auf hoher Ebene verwendet. Dadurch kann der Controller etwas von der Anzeige der Ansicht getrennt werden. Die Anmeldemethode des Controllers muss sich nicht darum kümmern, welche Komponenten die Ansicht bilden. Er erhält nur ein Ereignis und führt die Arbeit aus. Der Controller ist verantwortlich für den Ablauf der Anwendung.

Da das Ereignissystem vom Swing getrennt ist, verwende ich es in den Modellschichten, damit das Modell Ereignisse zurück an den Controller senden kann und der Controller diese Änderungen an die Benutzeroberfläche weiterleiten kann.

Das Modell und der Controller sind POJOs. Sie verstehen Ereignisse, aber das war's. Das Modell ist die Logik der Anwendung, einschließlich einer Ebene von DAOs, Diensten, die Hintergrundjobs ausführen können, jeder Dienstschicht, die mit dem Server kommuniziert, und Objekten, die die meisten Leute als DTOs bezeichnen.Ich verschreibe nicht die Vorstellung, dass ein DTO einfach einfache Getter/Setter-Strukturen sein sollte. Ich erlaube etwas Logik dort, weil sie das eine Ding sind, das zwischen allen Schichten schwimmt. Da jede Ebene Zugriff auf sie hat, stellen sie eine gute Möglichkeit dar, die Logik zu zentralisieren, die jede Ebene wiederverwenden kann. Die Ansicht, der Controller und das Modell können auf diese Methoden zugreifen, also legen Sie sie in das Objekt, das sich zwischen ihnen bewegt.

In der Regel liegt diese Logik näher an der Geschäftslogik oder Modellwartungslogik. Ich bin vorsichtig bei der Kopplung größerer Architekturen mit diesen Methoden. Diese Methoden werden nicht in die Datenbank sprechen, oder Server-Seite-Methoden aufrufen, so dass sie Verweise nicht zu größeren Architektur Stücke tragen zurück. Sie haben alle Vorteile von DTOs: leicht, leicht zu konstruieren, geringe Abhängigkeiten, aber immer noch die Prinzipien des Object Oriented Design: Einkapselung, Wiederverwendung und Informationsverbergung.

Ich habe auch begonnen, Spring für die Verdrahtung der Teile des Modells mit ihren Abhängigkeiten und Abhängigkeiten, die der Controller auf dem Modell hat, zu verwenden. Ich habe festgestellt, dass dieses Modell sehr gut funktioniert und viel angenehmer ist, als es nicht zu benutzen. Es ist auch schön, auf Technologien wie Spring JDBC-Vorlagen und JMS-Vorlagen zugreifen zu können, wenn ich diese Technologien verwende. Aber es ist optional.

Ich nie Controller wiederverwenden. Controller sind die spezifischsten Dinge in Ihrem System, und Generalisierungen machen sie nur schwieriger zu warten. Im View und Model gehören Allgemeingültigkeiten, weil es die Entwicklung erleichtert. Designmuster neigen dazu, sich auf diesen Seiten zu finden, aber selten im Controller. Controller sind einfache Methodenaufrufe hin und her.

Ich habe festgestellt, dass dies zu tun Gebäude Swing-UIs gemacht hat viel einfacher und geradlinig. Es ist weniger wahrscheinlich, dass ich in unendliche Ereignisschleifen gerät, wenn ich zwei Steuerelemente gleichzeitig höre und manipuliere. Ich finde es auch einfacher, das System zu testen und zu zerlegen, da ein Großteil meiner Logik außerhalb von Swings Reichweite existiert. Das macht die Funktionsprüfung möglich ohne eine riesige Toolkit versuchen Mausklicks zu simulieren usw.

Es gibt nicht viel Code hier zu illustrieren sorry, aber hoffe, das hilft.