Observable und Observer

Status
Nicht offen für weitere Antworten.

SnooP

Top Contributor
Um das Observerpattern umsetzen zu können gibt es ja in Java bereits die Klasse Observable und das Interface Observer. Ich hab jetzt das Problem das ich gegebene Modellklassen habe, die ich gerne mit einer gui verbinden möchte... die Veränderungen der Modellklassen möchte ich beobachten lassen - sprich ich möchte mir die Möglichkeit offen halten die Anzeige später beliebig zu ändern oder sogar mehrere Anzeigen gleichzeitig benachrichtigen zu können.. spricht also eigentlich alles für Observer.

Wie kann ich das jetzt mit Java-Boardmitteln erledigen? Ich müsste ja eigentlich meine Modellklasse von Observable erben lassen, dann wäre alles ganz prima... dummerweise hab ich natürlich bereits von ner anderen Klasse geerbt. Jetzt hab ich gedacht, dass ich in meiner Klasse einfach nen Feld für den Obserable mache, den ich bei einer Veränderung in meiner Modellklasse einfach benachrichtige und dieser ausgelagerte Observable ruft dann alle Observer auf.
Dummerweise ist Observable halt wirklich auf die Vererbung ausgelegt und die setChanged-Methode ist protected...

Wie mach ich das jetzt also vernünftig - bzw. wie würdet ihr vorgehen?
Soll ich ne eigene Klasse Observable machen an die ich von meiner Modellklasse delegiere und dort eine entsprechende Methode aufrufe bei einer Veränderung und die dann wiederum die setChanged-Methode aufruft? Klingt irgendwie auch blöd 😉

Oder soll ich mir nen eigenes Observerkonzept ausdenken mit Interfaces?
 
1. Möglichkeit: Oberklasse erbt von Observable
2. Möglichkeit: eigene Listener struktur

die fallen mir gerade ein
 
Hm jo... - Möglichkeit 1 find ich halt irgendwie unschön... an der Struktur ist eigentlich schon alles fertig und jetzt doch noch ne Oberklasse einzufügen.. hmm hmm... muss ich nochmal drüber nachdenken 😉

Möglichkeit 2 - okay - könnt ich machen... mein Modell kommuniziert in der Modellebene schon intern mitHilfe eines eigenen Listenerprinzips... wäre es jetzt sehr gegen MVC, wenn ich das vorhandene Listenerkonzept dazu verwende um gleichzeitig auch die View-Klassen zu informieren? Sprich ich adde als Listener gleichzeitig noch die GUI-Objekte?
Oder sollte ich parallel dazu lieber nen zusätzlichen Listener bauen, um noch flexibler zu sein?
 
Naja ob innere oder externe Klasse ist ja egal... wenn ich es an eine andere Klasse delegiere muss ich jenes Objekt aber auch benachrichtigen, dass sich der Zustand meines Modells geändert hat... also in etwa so, wie ichs beschrieben hab - dann muss ich bei der änderung noch mitgeben, was sich geändert hat und das in dem Delegat speichern...

Alles in allem recht umständlich..

ich glaube ich leite doch die Oberklasse von Observable ab 😉 - muss mal meinen Cheffe fragen, was der dazu sacht.
 
Wie wäre es mit PropertyChangeSupport wie bei Java-Beans?
z.B.
Code:
public class MyModel extends Whatever {
  private PropertyChangeSupport pcs = new PropertyChangeSupport(this);
  ...

  public void setFoo(Foo foo) {
    Foo oldValue = this.foo;
    this.foo = foo;
    pcs.firePropertyChange("foo", oldValue, foo);
  }
  
  public void addPropertyChangeListener(PropertyChangeListener listener) {
    pcs.addPropertyChangeListener(listener);
  }  

  public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) {
    pcs.addPropertyChangeListener(propertyName, listener);
  }

  public void removePropertyChangeListener(PropertyChangeListener listener) {
    pcs.removePropertyChangeListener(listener);
  }

  public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) {
    pcs.removePropertyChangeListener(propertyName, listener);
  }
}
 
Das liesse sich noch mit einem Proxy als Decorator "automatisieren", ist aber
schon zu viel Magic und etwas unangenehm beim Debuggen.
 
erzähl 😉 ... Magic klingt gut...

sowas ähnliches wie den PropertyChangeListener hatte ich mir selbst auch überlegt.. die Existenz von dem Teil ist mir aber in dem Kontext irgendwie nicht eingefallen 😉 - wäre ne alternative, allerdings die Geschichte mit den Einzeleigenschaften, die sich geändert haben find ich etwas unhübsch - mir hätte es gereicht, wenn ich das Datenmodell einfach mit dem Event mitschicken könnte - dann kann der Observer selbst entscheiden, was er denn nun für Daten braucht (Push).

Aber wie oben schon gesacht - habs jetzt doch mit dem Observable gelöst...
 
SnooP hat gesagt.:
erzähl 😉 ... Magic klingt gut...
Vergiss es gleich wieder. Es funktioniert nur, wenn man mit bekannten Interfaces arbeitet.
(siehe Proxy#newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h))
Da Deine Model-Objekte unterschiedlich sind bringt es nichts bzw. kann so nicht funktionieren.
 
Status
Nicht offen für weitere Antworten.

Zurück
Oben