- 1 Section
- 10 Lessons
- unbegrenzt
Observer
Stell dir vor, eine Zeitung erscheint. Müsste die Zeitung selbst jeden Leser einzeln informieren, würde sie an der Verwaltung von Adressen ersticken. Stattdessen: jeder, der die Zeitung lesen will, abonniert sie. Die Zeitung weiß nur „ich habe 50.000 Abonnenten" – nicht wer das einzeln ist. Wenn sie eine neue Ausgabe rausbringt, geht sie an alle Abonnenten. Genauso funktioniert das Observer-Pattern (Verhaltensmuster): ein Subject hält eine Liste von Observern. Wenn sich beim Subject etwas ändert, werden alle Observer automatisch benachrichtigt. Diese Lektion zeigt die Funktionsweise live, den Unterschied zu klassischem Pub/Sub, die UML-Struktur und typische Anwendungen wie Event-Listener, Newsletter und Reactive Programming.
1) Observer in Aktion – Aktienkurs mit Anzeigen
Eine klassische Anwendung: ein Aktienkurs (Subject) und mehrere Anzeigen (Observer) – ein Chart, eine Tabelle, ein Alarm-Modul. Wenn der Kurs sich ändert, sollen alle Anzeigen aktualisiert werden – und zwar ohne dass der Kurs jeden Empfänger einzeln kennt. Trag einen neuen Kurswert ein und beobachte:
📰 SUBJECT
AktienKurs
notifyAll() auf. Die Observer haben sich vorher via subscribe() registriert. Wenn du den Chart entfernst (Toggle), bekommt nur er keine Updates mehr – die anderen funktionieren weiter. Das nennt man lose Kopplung. Mehr in Interfaces und Dependency Inversion.2) Die Struktur des Observer-Musters
Im Kern braucht das Pattern vier Rollen: Subject (das beobachtete Objekt), Observer (Interface mit update()), ConcreteSubject und ConcreteObserver. Das Subject kennt seine Observer nur durch das Interface – nicht als konkrete Klassen. Hier die UML-Struktur:
update() auf jedem Observer auf. Diese lose Kopplung ist auch der Hauptvorteil ggü. direkten Methodenaufrufen. Mehr in Polymorphismus.3) Push vs. Pull – wer holt die Daten?
Es gibt zwei Varianten, wie das Subject die Observer benachrichtigt: Push (Daten werden mitgeschickt) und Pull (nur Hinweis „etwas hat sich geändert", Observer holt sich die Daten selbst). Beide haben ihre Berechtigung:
PUSH-Modell
Subject sendet die geänderten Daten direkt mit dem update()-Aufruf. Observer bekommt alles serviert.
+ einfacher Aufruf, kein Rück-Zugriff nötig
– Subject muss wissen, was Observer brauchen
observer.update(neuerKurs);
PULL-Modell
Subject sendet nur „etwas hat sich geändert" – Observer holen sich die Daten selbst über Getter.
+ Subject muss nichts wissen
– Observer braucht Referenz aufs Subject
observer.update(this); /* this = Subject */
java.util.Observer (heute deprecated) war Pull, java.beans.PropertyChangeListener ist Push (sendet alten und neuen Wert mit). Moderne Reactive-Frameworks (RxJS, Java Flow) sind Push-basiert. Faustregel: bei kleinen, klar definierten Daten → Push. Bei komplexen Objektgraphen → Pull.4) Bekannte Anwendungen
Das Observer-Muster ist eines der am häufigsten verwendeten Muster überhaupt – oft, ohne dass man es bemerkt. Wenn du JavaScript-Event-Listener nutzt, programmierst du Observer. Wichtige Beispiele:
- UI-Frameworks: Buttons, Eingabefelder etc. melden Klicks/Eingaben an angemeldete Listener. Beispiel:
button.addEventListener("click", handler)in JavaScript,button.setOnClickListener(...)in Android. - Reactive Programming: RxJava, RxJS, ReactiveX. Streams sind im Kern Observer-Ketten mit Operatoren.
- MVC / MVVM: die View observiert das Model. Ändert sich das Model, rendert die View neu (React Redux, Vue.js).
- Message-Broker: Kafka, RabbitMQ – Consumer abonnieren Topics. Konzeptionell verwandt mit Observer, aber als verteiltes System.
- Spring ApplicationEvents: Komponenten können Events publishen, beliebig viele
@EventListenerreagieren. - Datenbank-Trigger: Auf INSERT/UPDATE reagieren – konzeptionell Observer.
5) Observer-Pattern vs. Publish/Subscribe
Häufige Verwechslung in der Prüfung: Observer und Pub/Sub sind nicht das Gleiche, auch wenn sie sich ähneln. Der Unterschied:
| Observer | Publish/Subscribe |
|---|---|
| Direkter Aufruf zwischen Subject und Observer | Über einen Event-Bus / Broker als Vermittler |
| Subject kennt die Observer (in seiner Liste) | Publisher und Subscriber kennen sich gar nicht |
| In einem Prozess / einer Anwendung | Oft prozess- oder maschinenübergreifend |
| Synchron (meist) | Oft asynchron, mit Persistenz |
| Beispiel: Swing-Listener, RxJS | Beispiel: Kafka, RabbitMQ, AWS SNS |
Pub/Sub ist gewissermaßen die verteilte Variante des Observers. In Microservices-Architekturen ist es ein zentrales Pattern. Mehr in Microservices.
6) Fallstricke und Best Practices
Observer ist mächtig, aber hat ein paar typische Fehler, die in Prüfungsaufgaben gerne abgefragt werden:
- Memory Leaks durch nicht-entfernte Observer: wenn ein Observer registriert wird und nie wieder entfernt wird, hält das Subject einen Referenz auf ihn – der Garbage Collector kann ihn nicht aufräumen. Klassischer Fehler in Garbage Collection. Lösung:
detach()aufrufen oder WeakReferences verwenden. - Endlosschleifen: wenn Observer A das Subject ändert, wird Observer A wieder aufgerufen – Stack Overflow. Gegenmaßnahme: Flag „bin gerade beim Benachrichtigen" prüfen.
- Reihenfolge unklar: in welcher Reihenfolge werden Observer benachrichtigt? Spezifikation oft offen – nicht darauf verlassen.
- Fehler in einem Observer blockiert die anderen: wenn Observer 3 eine Exception wirft, kriegen Observer 4-10 keinen Update. Lösung:
try-catchum jeden Observer-Aufruf. - Thread-Sicherheit: wenn Observer aus verschiedenen Threads
attach/detachen und gleichzeitignotifyläuft – Race Condition. Mehr in Race Conditions.
Zusammenfassung
Observer (Verhaltensmuster) ist ein 1:n-Benachrichtigungsmechanismus: ein Subject hat eine Liste von Observern, die bei Statusänderung automatisch via update() informiert werden. Subject und Observer kennen sich nur über Interfaces → lose Kopplung. Zwei Varianten: Push (Daten werden mitgeschickt) und Pull (nur Hinweis, Observer holt selbst). Allgegenwärtig: UI-Event-Listener, Reactive-Frameworks, MVC, Datenbank-Trigger. Nicht zu verwechseln mit Pub/Sub (verteilte Variante mit Broker). Fallstricke: Memory Leaks durch nicht-entfernte Observer, Endlosschleifen, fehlerhafte Reihenfolge, Thread-Sicherheit.
Verwandte Lektionen: Strategy · MVC · Event-Listener · und mehrWeitere relevante LektionenWarum Entwurfsmuster?Abstrakte Klassen & InterfacesPolymorphismusSOLID-PrinzipienMicroservicesTrigger & ProzedurenRace Conditions
