Gibt es eine Sammlung von gemeinsam vereinbarten Entwurfsrichtlinien zum Trennen der Modellklassen von den View / Controller-Klassen in einer Java Swing-App? Ich bin nicht so besorgt, dass der View / Controller nichts über das Modell weiß, als umgekehrt: Ich möchte mein Modell so gestalten, dass es nichts über javax.swing weiß. Idealerweise sollte es eine einfache API haben, die es ermöglicht, von etwas so Primitivem wie einer CLI gesteuert zu werden. Es sollte lose gesagt ein "Motor" sein.
Die Kommunikation von GUI-Ereignissen mit dem Modell ist nicht allzu schwierig. Die Aktionsausführenden können die API des Modells aufrufen. Aber was ist, wenn das Modell seine eigenen Statusänderungen vornimmt, die in der GUI wiedergegeben werden müssen? Dafür ist "Zuhören" gedacht, aber selbst "Zuhören" ist nicht ganz passiv. Das Modell muss über das Hinzufügen eines Listeners informiert sein.
Das besondere Problem, das mich zum Nachdenken gebracht hat, betrifft eine Warteschlange mit Dateien. Auf der GUI-Seite befindet sich ein DefaultListModel
hinter a JList
, und es gibt einige GUI-Elemente, mit denen Sie Dateien aus dem Dateisystem auswählen und zur JList hinzufügen können. Auf der Modellseite möchte es die Dateien aus dem unteren Bereich dieser "Warteschlange" ziehen (wodurch sie aus der JList verschwinden) und auf irgendeine Weise verarbeiten. Tatsächlich ist der Modellcode bereits geschrieben - er verwaltet derzeit eine ArrayList<File>
und macht eine öffentliche add(File)
Methode verfügbar . Ich bin jedoch nicht in der Lage, mein Modell mit dem View / Controller zum Laufen zu bringen, ohne dass einige schwere, Swing-spezifische Änderungen am Modell vorgenommen werden müssen.
Ich bin sowohl in der Java- als auch in der GUI-Programmierung sehr neu, da ich bisher immer "Batch" - und "Back-End" -Programmierung durchgeführt habe - daher mein Interesse daran, eine strikte Trennung zwischen Modell und Benutzeroberfläche beizubehalten, wenn dies möglich ist und wenn dies möglich ist unterrichtet werden.
Antworten:
Es gibt keine allgemein vereinbarten (dh defacto ) Designrichtlinien für MVC. Es ist nicht ganz so schwer, es selbst zu tun, erfordert aber etwas Planung für Ihren Unterricht und viel Zeit und Geduld.
Der Grund, warum es keine definitive Lösung gibt, ist, dass es mehrere Möglichkeiten gibt, MVC durchzuführen, alle mit ihren Vor- und Nachteilen. Seien Sie also schlau und tun Sie, was am besten zu Ihnen passt.
Um Ihre Frage zu beantworten, möchten Sie den Controller auch von der Ansicht entkoppeln (sodass Sie dieselbe Geschäftsregellogik sowohl für eine Swing-App als auch für die Konsolen-App verwenden können). Im Swing-Beispiel möchten Sie den Controller vom
JWindow
Widget und jedem anderen Widget in Swing entkoppeln . Früher habe ich (vor der Verwendung der tatsächlichen Frameworks) eine Schnittstelle für die Ansicht erstellt, die der Controller verwendet:Für diese Lösung müssen Sie beim Start den Controller in der Ansicht registrieren.
Es könnte eine gute Idee sein, einen IoC-Container zu erstellen, um stattdessen das gesamte Setup für Sie durchzuführen.
Auf diese Weise können Sie jedoch nur Konsolenansichten mit denselben Controllern implementieren:
Der lustige Teil ist, wie man Event-Handling macht. Ich habe dies implementiert, indem ich die Ansicht über eine Schnittstelle beim Controller registrieren ließ. Dies erfolgt mithilfe des Observer-Musters (wenn Sie .NET verwenden, verwenden Sie stattdessen Ereignishandler). Hier ist ein Beispiel eines einfachen "Dokumentbeobachters", der signalisiert, wann ein Dokument gespeichert oder geladen wurde.
Auf diese Weise kann sich die Ansicht ordnungsgemäß selbst aktualisieren, da sie die Dokumentaktualisierungen abonniert. Alles was es tun muss, ist die
DocumentObserver
Schnittstelle zu implementieren :Ich hoffe, diese motivierenden Beispiele geben Ihnen einige Ideen, wie Sie es selbst machen können. Ich rate Ihnen jedoch dringend, die Verwendung von Frameworks in Java in Betracht zu ziehen, die die meisten Dinge für Sie erledigen, da Sie sonst viel Boilerplate-Code haben, dessen Schreiben lange dauert. Es gibt einige Rich Client Platforms (RCP), die Sie verwenden können, um einige der grundlegenden Funktionen zu implementieren, die Sie höchstwahrscheinlich benötigen, z. B. die anwendungsweite Dokumentenbehandlung und viele grundlegende Ereignisbehandlungen.
Es gibt ein paar, die ich mir vorstellen kann: Eclipse und Netbeans RCPs.
Sie müssen noch Controller und Modelle für sich selbst entwickeln, aber deshalb verwenden Sie ein ORM. Beispiel wäre Ruhezustand .
IoC-Container sind cool, aber es gibt auch Frameworks dafür. Zum Beispiel Spring (das unter anderem auch das Datenhandling übernimmt).
quelle
Ich gehe davon aus, dass wir manchmal Kompromisse eingehen müssen
Wie Sie sagen, wäre es großartig, wenn wir Änderungsbenachrichtigungen implizit verbreiten könnten, ohne dass das beobachtete Objekt eine explizite Infrastruktur dafür hat. Für gängige Imperativsprachen wie Java, C #, C ++ ist ihre Laufzeitarchitektur ohnehin ab sofort zu leicht. Damit meine ich, dass es derzeit nicht Teil der Sprachspezifikation ist.
In Ihrem speziellen Fall halte ich es nicht für eine schlechte Sache, eine generische Schnittstelle wie INotifyPropertyChanged (wie in c #) zu definieren / zu verwenden , da diese ohnehin nicht automatisch an eine Ansicht gekoppelt wird. Ich werde es dir sagen .
Auch hier stimme ich zu, dass es großartig wäre, wenn wir die Änderungsbenachrichtigung nicht selbst definieren müssten, aber wenn sie für alle Klassen implizit wäre, könnte dies zu einem Overhead führen.
quelle