Design Fragen

Status
Nicht offen für weitere Antworten.

Dunedain

Mitglied
Hallo,

bin vor kurzem in einigen Code Beispielen über AbstractActions gestolpert. Hab mich als Netbeans Matisse Anhänger jedoch noch nie ernsthaft damit befasst, da mir Matisse ja ActionListener serviert^^.
Wenn die implementierte Funktionaliät nicht mehrmals benötigt (Resourcen-Sharing) wird (Menü, Toolbar, Kontextmenü, ...) macht das ja imho keinen großen Unterschied, welchen der beiden man verwendet...?

Oder doch? Gibt es Gründe dafür oder dagegeben, AbstractAction Implementierungen (immer?) einem ActionListener vorzuziehen oder diese zu vermeiden?


Und gleich noch ne Frage hinterher 😀. Nach dem MVC Prinzip würden beide, also ActionListener und AbstractAction ja in den Bereich Controller fallen.
Wo implementiere ich diese Klassen? Als InnerClass des Formulars (um Zugriff auf die Formularkomponenten zu erlangen) oder als externe Klasse (und hangle mich dann via
Code:
//Ist improvisiert, d.h.: nicht getestet!
((JComponent)e.getSource()).getParent().getComponent(id).setXXX()
zu der Komponente durch, welche ich verwenden möchte?


Sry, die Fragen sind warscheinlich schwer zu beantworten und vermutlich auch "Geschmackssache". Aber trotzdem, ich bin für jede Meinung offen 😉
 
Hoi,

bei Punkt eins liegt es daran wie Dein Programm aufgebaut ist und wie oft Du ein und dieselbe Action ausführen willst. Nimmst Du den die "normale" Action, die Dir die Komponente liefert und willst zB von zwei verschiedenen Stellen auf dem GUI ebene diese Action bei einem Event ausführen lassen, kannst Du die behandelnde Routine einmal schreiben und die Komponenten registrieren. Was jetzt aber, wenn beide Komponente in Kombination in einer bestimmten Situation diese Action nicht mehr ausführen können soll? Beide Komponenten suchen und deregistrieren? Und wenn es 20 sind?
Mit einer selbstgeschriebenen Action wäre das ganz einfach möglich.

Nicht zu vergessen das DRY-Prinzip(Dont repeat yourself). Ein und dieselbe Action für 20 Komponenten. Immer wieder an verschiedenen Stellen im ActionListener dasselbe. Undd das in 25 Klassen. Viel Spaß beim Refactoring und beim bugfixen 😉


Zu Punkt 2:
Kommt drauf an 🙂
Als InnerClass mache ich das nur dann, wenn das "Formular" bzw. die Komponente für mich als abgeschlossene oder sehr spezielle Komponente gilt. Ansonsten kommt das klar in eine eigene Klasse und wird so behandelt, wie Du das beschrieben hast. Die Reaktionen darauf (zB einen Text in einem Textfeld ändern) können dann über verschiedenen Techniken erreicht werden. Interfaces oder Observer. Je nachdem was man machen will halt.

greetz
SLi
 
Wenn die implementierte Funktionaliät nicht mehrmals benötigt (Resourcen-Sharing) wird (Menü, Toolbar, Kontextmenü, ...) macht das ja imho keinen großen Unterschied, welchen der beiden man verwendet...?
Darum geht es im Prinzip. Wenn du eine Action nur einmal brauchst, ist es eigentlich egal.
Das schöne an einer AbstractAction: wenn dir 3 Monate später auffällt das du Action XY eben doch 2 mal brauchst, musst du keinen Code mehr ändern.
 
Sry, hat mal wieder etwas länger gedauert...
Konnte der Idee mit Observer und Interface nicht ganz nachverfolgen. Einige Google-Recherchen später...

Korrigiert mich, falls ich falsch liege^^
  • Die Daten Klasse (Modell) ist Observable
    [list:1e58ec5d65]
  • Die Connector Klasse (Controller) hält eine Referenz auf das Modell.
  • Es implementiert ein Interface, welches Lese- und Schreibmethoden auf das Modell definiert.
  • Außerdem eine Synchronisationsfunktion, welche die aktuellen Werte an die View(s) übermittelt.
  • Die Gui Klasse (View) ist Observer der Datenklasse.
  • Außerdem hält sie eine Referenz auf den Controller zur Manipulation und Synchronisation der Daten.
  • Die Speicherung der Referenz auf die Datenklasse zur DeRegistrierung als Observer ist nicht zwingend erforderlich(?)....
  • Außerdem werden diverse Listener (DocumentListener, FocusListener, ChangeListener, ...)registriert, welche die GUI Elemente auf Änderungen überwachen. Entsprechende Änderungen werden über den Controller an das Modell weitergegeben.
[/list:u:1e58ec5d65]

Ist das soweit richtig?
Oder sollte die View tatsächlich eine Referenz auf das Modell halten und die Daten direkt aus den Listenern heraus aktualisieren?
Oder sollten die oben in der View beschriebenen Listener alle im Controller implementiert sein und dieser dann die Daten manipulieren (Dadurch würde jede View allerdings einen eigenen Controller benötigen...)?

Tja, Google hat mir zu diesem Thema die oben beschriebenen (und auch noch andere) Lösungsansätze gezeigt. Aber welcher ist nun der richtige?


Davon mal abgesehen, den Weg dieser Bindungen "zu Fuß" zu gehen, machen die Beans- bzw. Swing Bindings doch genau dass, oder?
 
Hoi,

wie Du es letztendlich realisierst, ist Dir überlassen.
Es gibt da nicht DEN Weg.

Aber ganz grob zum Observer Pattern.
Deine Klasse die beobachtet werden soll ist von Observer abgeleitet. Nach einer Veränderung der Daten, die bekannt gemacht werden soll, rufst Du setChanged(), notifyObservers() clearChanged() oder so auf.

Die Klassen die beobachten, implementieren Observable, was zur Folge hat, dass Du die Methode update(Object, Object) impplementieren musst. Ich gleich das zweite Objekt ist das geänderte Objekt, welches Du beobachtest. Im beobachter musst Du Dich jedoch zuerst beim Observer registrieren.

Ob Du nun in der GUI Klasse die updateMethode hast und die Oberfläche updatest oder ob ein Controller den Beobachter spielt und Du mittels Interfaces die Oberfläche updatest ist wie gesagt Dir überlassen.
Hängt ja auch immer davon ab wieviel arbeit Du Dir machen willst und wie sauber Du es trennen willst.

greetz
SLi
 
Danke, dass ist schonmal sehr aufschlussreich 🙂

Im Moment geht es mir jedoch nicht um eine konkrete Implementierung, sodern darm, wie man es machen sollte. Das die Wirklichkeit meist anders aussieht, ist ja bei vielen Design- und Planungs Prozessen der Fall... 😉
 
Status
Nicht offen für weitere Antworten.

Neue Themen


Zurück
Oben