Observer Pattern
Table of Contents
1. Einführendes Beispiel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
2. Observer Pattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
3. Lösung mittels Observer Pattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
Quellen:
• Freeman, Eric & Robson Elisabeth: Entwurfsmuster von Kopf bis Fuß, 2. Auflage, O´Reilly,
Heidelberg, 2015
1
1. Einführendes Beispiel
Wir sollen eine erweiterbare Wetterstation entwickeln.
Diese besteht einerseits aus dem Sensorbereich (Sensor für Luftfeuchtigkeit, Temperatur,
Luftdruck, …) und andererseits aus dem Anzeigegerät, welches unterschiedliche Daten anzeigt
(aktulle Daten, Statistiken, Vorhersagen, …).
Wenn sich Messwerte verändern, hat dies Auswirkungen auf die unterschiedlichen Anzeigen.
Vereinfacht könnte die Lösung wie folgt aussehen:
public class WeatherData {
// ... variables
public void dataChanged() {
float temp = getTemperature();
float hum = getHumidity();
float baro = getBarometricPressure();
[Link](temp, hum, baro);
[Link](temp, hum, baro);
[Link](temp, hum, baro);
}
// .... other methods
}
Analyse der Lösung:
Welche Aussagen treffen auf den ersten Grobentwurf zu?
☐ Es wird auf eine konkrte Implementierung und nicht auf eine Schnittstelle entwickelt
☐ Der Code muss für jedes neue Anzeigeelement geändert werden
☐ Es existiert keine Möglichkeit zur Laufzeit Anzeigeelemente hinzuzufügen (oder auch zu
entfernen)
☐ Die Anzeigeelemente implementieren keine gemeinsame Schnittstelle
☐ Der Teil, der sich ändert, wurde nicht gekapselt
☐ Die Kapselung der Klasse WeatherData wurde verletzt
2
2. Observer Pattern
Das Observer Pattern definiert eine Eins-zu-viele-Abhängigkeit zwischen
Objekten in der Art, dass alle abhängigen Objekte benachrichtigt werden, wenn
sich der Zustand des einen Objekts ändert.
Das Observer Pattern ist gut vergleichbar mit einem Zeitungs-Abonnement.
Ein Verlag bringt Zeitungen heraus. Damit der Kunde nicht ständig nachfragen muss, ob bereits
eine neue Ausgabe erschienen ist und damit er keine neue Ausgabe verpasst schließt er ein Abo ab.
Jede neue Ausgabe wird ihm ab diesem Zeitpunkt automatisch zugestellt.
Verliert er das Interesse an der Zeitung beendet er sein Abonnement und er bekommt ab diesem
Zeitpunkt keine Ausgaben mehr zugesandt.
Das ganze wird also aufgeteilt in Observable (das Subjekt, das überwacht wird) und Observer (die
Beobachter, die über Änderungen informiert werden sollen).
Observable Observer
Verwaltung der Beobachter: stellt einheitliche update() Methode bereit
• addObserver()
• deleteObserver()
• notifyObservers()
• setChanged()
(notwendig, damit Benachrichtigung
tatsächlich durchgeführt wird)
Java stellt dazu eine Klasse Observable und ein zugehöriges Interface Observer bereit. Somit müssen
wir die Verwaltung der Observer-Liste nicht selbst implementieren.
Leider wurden Observer und Observable mit dem JDK 9 deprecated. Als
alternatives Eventmodell wird das [Link]-Package vorgeschlagen.
Schwachpunkte des bis JDK 8 bereitgestellten Observer Patterns:
• Observable ist eine Klasse
◦ Verletzt das Entwurfsprinzip, möglichst auf Interfaces zu programmieren
◦ Observable muss durch Vererbung erweitert werden
◦ keine Erweiterung einer anderen Klasse im gleichen Schritt möglich (keine
Mehrfachvererbung)
• setChanged() ist protected
◦ kann also nur in Unterklassen von Observable aufgerufen werden, dies zwingt uns zur
Vererbung und nimmt die Möglichkeit, dass eine Observable-Instanz mit unseren eigenen
Objekten zusammengesetzt werden kann
◦ Verletzt das Entwurfsprinzip: die Komposition ist der Vererbung vorzuziehen
3
3. Lösung mittels Observer Pattern
Bezugnehmend auf unser einführendes Beispiel würde die Lösung wie folgt aussehen:
Implementieren Sie das eben besprochene Beispiel.
Erzeugen Sie einen Thread, der die Messdaten alle 2 Sekunden aktualisiert.
Implementieren Sie mindestens eine Display-Klasse, welche über die Änderungen
informiert werden soll und diese ausgibt!