Observer Pattern

Dieser Beitrag in der Reihe Design-Pattern ist dem Observer-Pattern (Der Beobachter) gewidmet. Es gehört in die Kategorie der Verhaltensmuster.

Welches Problem kann das Observer-Pattern lösen?

Es existiert ein Objekt A (Subjekt), welches Änderungen unterliegt: Eigenschaften ändern sich, Status ändert sich etc. Es existiert außerdem ein Objekt B (Beobachter) welches über die Änderungen des Objektes A informiert werden soll.

Eine einfache Lösung

Naiv könnte man die Situation lösen, indem Objekt A einen Verweis auf Objekt B hält und über diesen Verweis die entsprechenden Funktionen von Objekt B im Falle einer Änderung aufruft. Objekt B sollte ebenfalls einen Verweis auf das Objekt A speichern, um die benötigten Daten vom beobachteten Objekt A abzurufen.
Mit dieser Lösung hat man jedoch das Objekt B sehr eng an das Objekt A gekoppelt. Was ist nun wenn Objekte verschiedener Klassen über Änderungen unterrichtet werden müssen?

Eine bessere Lösung

Es ist also sinnvoll, eine einheitliche Schnittstelle (Interface) für alle Objekte zu schaffen, die über Änderungen informiert werden sollen. Diese Schnittstelle bezeichnen wir als Observer. Sie enthält nur eine Methode, die signalisiert, dass sich (irgendetwas) geändert hat. Den Sachverhalt zeigt folgendes UML-Diagramm.

PatternObserver

Objekt A (Klasse Subjekt) informiert alle angemeldeten Observer (Schnittstelle Observer), die sich Änderungen wiederum über eine öffentliche Methode (update) dann vom Objekt A holen können.

Objekt A muss nun eine Collection aus Observern verwalten. Es bietet die Möglichkeit sich bei ihm als Observer an -und abzumelden. Tritt eine Änderung ein, iteriert Objekt A durch seine angemeldeten Observer und ruft jeweils die Änderungsmethode der Schnittstelle Observer auf.
Objekt B implementiert die Schnittstelle Observer und meldet sich bei Objekt A als Observer an. Damit bleibt das konkrete Objekt B unbekannt für Objekt A und es wurde eine lose Koppelung geschaffen. Andere Klassen können ebenfalls diese Schnittstelle implementieren und so über Änderungen des Objekt A informiert werden. Die Abstraktion durch das Interface Observer schafft hier Unabhängigkeit und damit Flexibilität.

Natürlich ist es möglich, das Objekt A seinen Beobachtern gegenüber nicht konkret sondern nur abstrakt über ein weiteres Interface bekannt zu machen: Observable. Diese Schnittstelle würde lediglich die Methoden nach außen freigeben, die zur An/Abmeldung von Beobachtern sowie zur Freigabe der Daten (die für Beobachter relevant sind) benötigt werden. Diese gut entkoppelte Variante sieht im Klassendiagramm wie folgt aus:

PatternObserver2

Observer Pattern – Beobachter und Subjekt durch Interfaces entkoppelt

Das Observer Pattern wird auch als Publisher-Subscriber Pattern bezeichnet. Publisher sind Subjekte, die Änderungen bekannt geben, Subscriber sind Beobachter die darauf reagieren.
MVC ist eine wichtige Anwendung für dieses Pattern. Dort wird der View (Observer) in dieser Weise über Änderungen der Daten (Model) informiert. Generell erfreut sich das Muster großer Beliebtheit in der Event-Verarbeitung. So z.Bsp in Java Swing und .Net.

Weiterlesen:

Autor:    Michael Keutel | 01.02.2013