Menu
Coddy logo textTech

Observer-Muster

Teil des Abschnitts Object Oriented Programming der Python-Journey von Coddy — Lektion 47 von 64.

Das Observer-Pattern erzeugt eine Eins-zu-viele-Beziehung, bei der ein Objekt (Subjekt) mehrere Objekte (Beobachter) benachrichtigt, wenn sich sein Zustand ändert.

Hier ist eine einfache Subject-Klasse, die Observer verwaltet:

class Subject:
    def __init__(self):
        self._observers = []
    
    def add_observer(self, observer):
        self._observers.append(observer)
    
    def notify(self, message):
        for observer in self._observers:
            observer.update(message)

Das Subjekt führt eine Liste von Beobachtern und kann sie alle gleichzeitig benachrichtigen.

Erstellen Sie einfache Observer-Klassen:

class EmailNotifier:
    def update(self, message):
        print(f"Email sent: {message}")

class SMSNotifier:
    def update(self, message):
        print(f"SMS sent: {message}")

Jeder Beobachter hat eine update-Methode, die aufgerufen wird, wenn er benachrichtigt wird.

Verwenden Sie das Observer-Pattern:

# Subjekt erstellen
news = Subject()

# Observer erstellen
email = EmailNotifier()
sms = SMSNotifier()

# Observer zum Subjekt hinzufügen
news.add_observer(email)
news.add_observer(sms)

# Alle Observer benachrichtigen
news.notify("Breaking news: Python is awesome!")

Erstellen Sie ein praktisches Beispiel mit einem Aktienkurs-Tracker:

class Stock:
    def __init__(self, symbol, price):
        self.symbol = symbol
        self._price = price
        self._observers = []
    
    def add_observer(self, observer):
        self._observers.append(observer)
    
    def set_price(self, price):
        self._price = price
        self.notify()
    
    def notify(self):
        for observer in self._observers:
            observer.update(self.symbol, self._price)

class Investor:
    def __init__(self, name):
        self.name = name
    
    def update(self, symbol, price):
        print(f"{self.name} notified: {symbol} is now ${price}")

# Verwenden Sie den Aktien-Tracker
apple_stock = Stock("AAPL", 150)

investor1 = Investor("Alice")
investor2 = Investor("Bob")

apple_stock.add_observer(investor1)
apple_stock.add_observer(investor2)

apple_stock.set_price(155)  # Benachrichtigt alle Investoren

Ausgabe:

Email sent: Breaking news: Python is awesome!
SMS sent: Breaking news: Python is awesome!
Alice notified: AAPL is now $155
Bob notified: AAPL is now $155

Kernpunkt: Das Observer-Pattern ermöglicht es einem Objekt, viele andere automatisch zu benachrichtigen, wenn sich etwas ändert. Das Subjekt verwaltet eine Liste von Observern und ruft deren update-Methode auf, wenn dies erforderlich ist. Dies ist nützlich für Benachrichtigungen, Ereignissysteme und um mehrere Teile Ihrer Anwendung synchron zu halten.

challenge icon

Aufgabe

Mittel

Implementieren Sie das Observer-Pattern, indem Sie ein Wetterüberwachungssystem erstellen. Sie müssen zwei Klassen in den dafür vorgesehenen Bereichen des Codes erstellen.

Schritt 1: Erstellen Sie die Klasse WeatherStation

Schreiben Sie Ihre WeatherStation-Klasse dort, wo der Kommentar es angibt. Diese Klasse sollte:

  • Von der Klasse Subject erben (verwenden Sie class WeatherStation(Subject):)
  • Initialisieren mit:
    • Rufen Sie den Konstruktor der Elternklasse mit super().__init__() auf
    • Setzen Sie die Anfangstemperatur auf 0 unter Verwendung eines privaten Attributs self._temperature
  • Implementieren Sie <strong>set_temperature(self, temperature)</strong>:
    • Aktualisieren Sie das private Temperatur-Attribut
    • Rufen Sie self.notify(self._temperature) auf, um alle Beobachter zu benachrichtigen
  • Implementieren Sie <strong>get_temperature(self)</strong>:
    • Geben Sie den aktuellen Temperaturwert zurück

Schritt 2: Erstellen Sie die Klasse WeatherDisplay

Schreiben Sie Ihre WeatherDisplay-Klasse dort, wo der Kommentar es angibt. Diese Klasse sollte:

  • Von der Klasse Observer erben (verwenden Sie class WeatherDisplay(Observer):)
  • Initialisieren mit:
    • Akzeptieren Sie einen name-Parameter
    • Speichern Sie den Namen als self.name
  • Implementieren Sie <strong>update(self, temperature)</strong>:
    • Geben Sie die Nachricht zur Temperaturaktualisierung genau im unten gezeigten Format aus

Nachrichtenformat:

Wenn ein Display eine Temperaturaktualisierung erhält, muss es genau Folgendes ausgeben:

Display [name]: Current temperature is [temperature]C

Beispielhafte Verwendung:

# Create weather station and displays
station = WeatherStation()
phone_display = WeatherDisplay("Phone")
tablet_display = WeatherDisplay("Tablet")

# Attach displays to station
station.attach(phone_display)
station.attach(tablet_display)

# Update temperature - both displays will be notified
station.set_temperature(25.5)

# Output:
# Display Phone: Current temperature is 25.5C
# Display Tablet: Current temperature is 25.5C

Wichtige Hinweise:

  • Die Methoden attach() und detach() sind bereits in der Basisklasse Subject implementiert – Sie müssen diese in Ihrer WeatherStation-Klasse weder implementieren noch aufrufen
  • Im obigen Verwendungsbeispiel wird station.attach(phone_display) vom Benutzer Ihrer Klasse aufgerufen, nicht innerhalb Ihrer WeatherStation-Implementierung
  • Ihre WeatherStation muss lediglich self.notify() aufrufen, wenn sich die Temperatur ändert – die Basisklasse Subject kümmert sich um den Rest
  • Konzentrieren Sie sich darauf, die drei erforderlichen Methoden in WeatherStation und die zwei erforderlichen Methoden in WeatherDisplay wie oben angegeben zu implementieren

Spickzettel

Das Observer-Muster (Beobachter-Muster) erstellt eine Eins-zu-viele-Beziehung, bei der ein Objekt (Subjekt) mehrere Objekte (Beobachter) benachrichtigt, wenn sich sein Zustand ändert.

Basis-Subjekt-Klasse, die Beobachter verwaltet:

class Subject:
    def __init__(self):
        self._observers = []
    
    def add_observer(self, observer):
        self._observers.append(observer)
    
    def notify(self, message):
        for observer in self._observers:
            observer.update(message)

Beobachter-Klassen mit der Methode update:

class EmailNotifier:
    def update(self, message):
        print(f"Email sent: {message}")

class SMSNotifier:
    def update(self, message):
        print(f"SMS sent: {message}")

Verwendung des Observer-Musters:

# Subjekt erstellen
news = Subject()

# Beobachter erstellen
email = EmailNotifier()
sms = SMSNotifier()

# Beobachter zum Subjekt hinzufügen
news.add_observer(email)
news.add_observer(sms)

# Alle Beobachter benachrichtigen
news.notify("Breaking news: Python is awesome!")

Praktisches Beispiel mit einem Aktienkurs-Tracker:

class Stock:
    def __init__(self, symbol, price):
        self.symbol = symbol
        self._price = price
        self._observers = []
    
    def add_observer(self, observer):
        self._observers.append(observer)
    
    def set_price(self, price):
        self._price = price
        self.notify()
    
    def notify(self):
        for observer in self._observers:
            observer.update(self.symbol, self._price)

class Investor:
    def __init__(self, name):
        self.name = name
    
    def update(self, symbol, price):
        print(f"{self.name} notified: {symbol} is now ${price}")

Das Observer-Muster ermöglicht es einem Objekt, viele andere automatisch zu benachrichtigen, wenn sich etwas ändert. Das Subjekt verwaltet eine Liste von Beobachtern und ruft deren Methode update auf, wenn dies erforderlich ist.

Probier es selbst

class Subject:
    def __init__(self):
        self._observers = []
    
    def attach(self, observer):
        self._observers.append(observer)
        
    def detach(self, observer):
        self._observers.remove(observer)
        
    def notify(self, data):
        for observer in self._observers:
            observer.update(data)
            
class Observer:
    def update(self, data):
        pass

# Schreiben Sie hier Ihre WeatherStation-Klasse

# Schreiben Sie hier Ihre WeatherDisplay-Klasse

quiz iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Object Oriented Programming