Observer-Muster
Das Observer-Muster definiert eine Eins-zu-Viele-Abhängigkeit zwischen Objekten, sodass alle Abhängigen automatisch benachrichtigt und aktualisiert werden, wenn ein Objekt seinen Zustand ändert. Verwende es, wenn mehrere Teile deines Systems auf Änderungen einer einzigen Quelle der Wahrheit reagieren müssen.
Überblick
Das Observer-Muster etabliert einen Abonnement-Mechanismus, der es mehreren Objekten ermöglicht, auf Ereignisse eines anderen Objekts zu lauschen. Das Subject führt eine Liste von Beobachtern und benachrichtigt sie bei jeder Zustandsänderung, ohne zu wissen oder sich darum zu kümmern, was diese Beobachter mit der Information machen. Das entkoppelt die Änderungsquelle von den Änderungskonsumenten und macht es einfach, neue Reaktionen hinzuzufügen, ohne den Emitter zu modifizieren.
Wann verwenden
- Eine Änderung in einem Objekt soll Updates in anderen auslösen, und du willst keine enge Kopplung zwischen ihnen.
- Die Anzahl der Abhängigen ist zur Kompilierzeit unbekannt oder ändert sich zur Laufzeit (dynamische Abonnements).
- Du baust eine ereignisgesteuerte Architektur — UI-Event-Handler, Message-Broker, Reactive Streams.
Beispiel
interface Observer<T> {
update(data: T): void;
}
class Subject<T> {
private observers: Observer<T>[] = [];
subscribe(observer: Observer<T>) {
this.observers.push(observer);
}
unsubscribe(observer: Observer<T>) {
this.observers = this.observers.filter(o => o !== observer);
}
notify(data: T) {
this.observers.forEach(o => o.update(data));
}
}
const priceTracker = new Subject<number>();
priceTracker.subscribe({
update(price) { console.log(`Dashboard: $${price}`); }
});
priceTracker.subscribe({
update(price) {
if (price < 100) console.log('Alarm: Preis gefallen!');
}
});
priceTracker.notify(95);Vorteile
- Lose Kopplung — das Subject weiß über seine Beobachter nur die Schnittstelle.
- Neue Beobachter können jederzeit hinzugefügt werden, ohne bestehenden Code zu ändern.
- Folgt dem Open/Closed-Prinzip: offen für Erweiterung, geschlossen für Modifikation.
Nachteile
- Die Benachrichtigungsreihenfolge ist nicht garantiert, was subtile Bugs verursachen kann, wenn Beobachter voneinander abhängen.
- Memory Leaks können auftreten, wenn Beobachter nicht ordnungsgemäß abgemeldet werden.
- Kaskadierende Updates zu debuggen kann schwierig sein, wenn viele Beobachter auf dasselbe Ereignis reagieren.