1. Was ist das Observer Pattern
Das Observer Pattern ist ein Verhaltensmuster, das verwendet wird, um eine Abhängigkeit von einem zu vielen Objekten herzustellen. Speziell werden alle Abhängigkeiten (auch als Beobachter bezeichnet) benachrichtigt und automatisch aktualisiert, wenn sich ein Objekt (auch als Subjekt oder Beobachtbares bezeichnet) ändert. Dieses Muster ermöglicht eine lose Kopplung zwischen Subjekten und Beobachtern, wodurch eine Entkopplung und Flexibilität zwischen Objekten erreicht wird.
2. Merkmale und Vorteile des Observer Patterns
Das Observer Pattern hat die folgenden Merkmale und Vorteile:
- Lose Kopplung zwischen Subjekten und Beobachtern, wobei das Subjekt die spezifischen Implementierungsdetails der Beobachter nicht kennen muss.
- Dynamische Hinzufügung und Entfernung von Beobachtern, was das System flexibler macht.
- Befolgt das offene-geschlossene Prinzip zwischen Subjekten und Beobachtern und ermöglicht eine unabhängige Erweiterung und Wiederverwendbarkeit.
- Kann eine Abhängigkeitsbeziehung von eins zu vielen herstellen, wobei ein Subjekt mehrere Beobachter haben kann.
3. Beispiele für praktische Anwendungen des Observer Patterns
Das Observer Pattern hat viele praktische Anwendungen im wirklichen Leben, wie z. B.:
- Ereignisbehandlungsmechanismus in GUI-Schnittstellen, z. B. die Behandlung von Aktionen beim Klicken einer Schaltfläche.
- Echtzeit-Börsenkursbenachrichtigungen.
- Benachrichtigung von Werbeaktionen auf E-Commerce-Plattformen.
4. Implementierung des Observer Patterns in Golang
4.1 UML-Klassendiagramm
4.2 Beispielbeschreibung
In diesem Beispiel haben wir ein Subjekt (Subject) und zwei Beobachter (ObserverA und ObserverB). Das Subjekt kann Beobachter registrieren, entfernen und benachrichtigen.
4.3 Implementierungsschritte
4.3.1 Erstellen Sie eine Subjekt-Schnittstelle und eine konkrete Subjekt-Klasse
type Subject interface {
RegisterObserver(observer Observer)
RemoveObserver(observer Observer)
NotifyObservers()
}
type ConcreteSubject struct {
observers []Observer
}
// Registrieren Sie das Listener-Objekt
func (subject *ConcreteSubject) RegisterObserver(observer Observer) {
subject.observers = append(subject.observers, observer)
}
// Entfernen Sie das Listener-Objekt
func (subject *ConcreteSubject) RemoveObserver(observer Observer) {
for i, obs := range subject.observers {
if obs == observer {
subject.observers = append(subject.observers[:i], subject.observers[i+1:]...)
break
}
}
}
// Ereignisbenachrichtigung auslösen
func (subject *ConcreteSubject) NotifyObservers() {
for _, observer := range subject.observers {
observer.Update()
}
}
4.3.2 Erstellen Sie eine Beobachter-Schnittstelle und konkrete Beobachterklassen
type Observer interface {
Update()
}
type ConcreteObserverA struct {}
func (observer *ConcreteObserverA) Update() {
fmt.Println("Beobachter A wird benachrichtigt.")
}
type ConcreteObserverB struct {}
func (observer *ConcreteObserverB) Update() {
fmt.Println("Beobachter B wird benachrichtigt.")
}
4.4 Beispielcode-Demo
func main() {
subject := &ConcreteSubject{}
observerA := &ConcreteObserverA{}
observerB := &ConcreteObserverB{}
subject.RegisterObserver(observerA)
subject.RegisterObserver(observerB)
subject.NotifyObservers()
subject.RemoveObserver(observerA)
subject.NotifyObservers()
}
Ausgabe:
Beobachter A wird benachrichtigt.
Beobachter B wird benachrichtigt.
Beobachter B wird benachrichtigt.
Der obige Beispielcode zeigt die spezifische Implementierung des Observer Patterns. Das Subjekt (ConcreteSubject) hat zwei Beobachter (ObserverA und ObserverB) registriert und dann diese beiden Beobachter benachrichtigt. Anschließend wurde Beobachter A vom Subjekt abgemeldet und der verbleibende Beobachter B erneut benachrichtigt.