Vererbung vs Komposition

Hallö,

mir schwirrt grade ne Frage zu obigem Thema im Kopf herum und hab sie wahrscheinlich schon wieder viel zu sehr zerdacht:
In meiner GUI gibt es eine JList in der abhängig von Benutzerinteraktionen Elemente hinzugefügt werden. Im Moment hab ich eine eigene Spezialisierung von JList die bei einer anderen Klasse als Observer angemeldet ist. Von dieser anderen Klasse empfängt meine JList-Spezialisierung Daten und abhägig davon welche, wird eine oder werden mehrere neue Einträge dem Model hinzugefügt.

Meine JList-Klasse gibts also nur um zu prüfen welche Daten vom Observable übermittelt werden und diese dementsprechend ans Model weiterzuleiten.

Ist es sinnvoll dafür eine eigene JList Klasse zu erstellen? Ich meine das ganze könnte ich auch in einer neuen Klasse managen, die eben die JList und das zugehörige Model kennt und die ganzen Abfragen welche Einträge dem Model hinzugefügt werden befinden sich dann eben “extern”, außerhalb vom Model und außerhalb der JList.

edit: oO Rechtschreibfehler im Titel…wieso kann ich den nicht mehr editieren??!
Soll natürlich “Komposition” heißen

Den Titel kann man wohl noch ändern, wenn man beim Editieren auf “Go Advanced” geht (auf Deutsch vermutlich “Erweiterter Editor” oder so…).

Zur Fraqe: Ja, ich persönlich würde sagen, dass das ausgelagert sein sollte. Insbesondere hat das mit dem GUI ja nichts zu tun. Wenn das ein eigenes ListModel wäre, würde ich es noch verstehen, aber in der JList hat so eine Funktionalität IMHO nichts verloren. (Es gibt insgesamt nur “relativ wenige” Fälle, wo man von einer GUI-Component erben muss oder sollte. Klar, von JPanel wenn man selbst etwas zeichnen will, und dann vielleicht noch für irgendwelche tricky-fancy-Spezialfunktionen, aber … sonst eher selten)

Dass ich ein eigenes ListModel ableite ist mir auch in den Sinn gekommen. Dann dachte ich mir aber, da die KLasse JList an sich ja als Controller in der graphischen Komponente JList fungiert (korrigiert michw enn ich falsch liege) ist genau da die richtige Stelle um

  • als Observer von außen benachrichtigt zu werden
    und
  • um die ankommenden Daten richtig zu interpretieren (if cases) um sie dem Model letztendlich weiterzuvermittlen.

Diese 2 Punkte sah und seh ich auch als Argument gegen ein eigenes Model:

  • Das Model dient als reine “dumme” Datenhaltung, es sollte daher nicht Observer sein
  • Im Model sollte keine Logik vorkommen, deswegen ist hier auch der falsche Platz für irgendwelche if-Bedingungen die sich auf die aktuelle View beziehen

Es kommt auf den Kontext an in dem man JList betrachtet.

Im Kontext von Swing kann man JList als eine Komponente betrachten die View und Controller beinhaltet.

Intern läuft bei einer JList das ganze nach dem MVC ab. Ein MouseEvent wird wahrgenommen. Dann wird entschieden was dieser zu bedeuten hat (Controller). Aha, click auf 3.tes Element. Jetzt wird nachgefragt was im ListModel (Model) an dritter Stelle ist. Damit werden dann die angehängten Listener (mittels Controller) benachrichtigt.

Wenn ich allerdings eine ganze Anwendung betrachte, dann ist JList lediglich eine View.

In einer JList wird ein Element ausgewählt.
Ein darauf registrierter SelectionListener reagiert darauf und sendet eine Nachricht an einen Controller.
Dieser Controller empfängt das ausgewählte Element und
ändert ein Model das zu einer anderen View (z.B. Detailansicht) gehört,
die daraufhin aktualisiert wird.

ListModel und den Controller-Part aus einer JList wiederzuverwenden ist zwar ein netter Gedanke, aber das sorgt eher für Verwirrung da bei diesen Klassen viel zu viel dabei ist, dass mit Swing zu tun hat.

@Majora : Was willst du damit nun sagen? Weder von ListModel noch von JList erben und die gewünschte Funktionalität in eine KLasse legen die List + Model als Variable hält?

Ich teile beide deiner Betrachtungsweisen, aber imo schließt die eine die andere nicht aus.

Eine JList ist eine View kein Controller. Zwar stehen im JList.java File ein paar Klassen die einen Controller darstellen, das macht die JList aber nicht zu einem Controller. Diese Controller sind eigene Objekte.

Dein Anwendungsfall ist eigentlich genau das was ein Controller macht. Irgendein Ereignis tritt auf (Observer wird upgedated) und daraufhin soll das Model verändert werden (Elemente hinzufügen). Der Controller braucht bei dir die View gar nicht kennen, die wird von Model über die neuen Einträge informiert.

Nach meinem bisherigen Verständnis von Swing-Klassen die ein Model (und einen Renderer) besitzen ist die eigentliche Klasse (JTable, JList, JTree etc.) Controller und View in einem und das zugehörige Model eben das Model in MVC. Liege ich da etwa falsch?

Die JList selber ist kein Controller - da steht nix von implements XXXListener - sehr wohl aber besitzt sie eine private Klasse private class ListListener implements ListSelectionListener, ListDataListener die den Controller darstellt.

Ausserdem wird auch noch eine Menge von der ListUI gesteuert.

Das IMHO entscheidende bei MVC ist die Trennung von Modell und View. Über die Frage, was ein Controller in der einen oder anderen Unter-Ausprägung dieses Musters denn genau ist, kann man lange streiten. Es gibt allerdings keinen Grund, diese Klasse, die du da bastelst, von JList erben zu lassen (du willst ja nicht irgendwelche protected-Methoden von JList aufrufen oder überschreiben…). Die Funktionalität kann komplett losgelöst davon sein.

Okay, das klingt einleuchtend.

Nur nochmal um sicherzugehen:
Für einen solchen Fall baut man sich also eine Klasse die ungefähr so aussieht

public class MyJList implements MyObserver{
   JList jlist;
   ListModel model;

   ... //konstruktor, setter und getter

   public void update(...){ //MyObserver Methode   
       //hier verrücktes zeugs tun, oder nochmal in ne methode auslagern
   }
}

Tatsächlich wüßte ich auf Basis des bisher beschriebenen nichtmal, wozu dort die List-Instanz gebraucht wird. Soll nicht nur der Observer auf irgendwas hören, und die Daten dann ggf. ins ListModel packen? (Das kann an dieser Stelle und zu diesem Zeck dann als ‘DefaultListModel’ bekannt sein) ?

Stimmt, mein Fehler, da hast du Recht.
Danke für eure Antworten