Menu
Coddy logo textTech

Observer-Muster

Teil des Abschnitts Objektorientierte Programmierung der Python-Journey von Coddy. Lektion 47 von 64.

Das Beobachter-Muster erstellt 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 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)

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

Erstelle einfache Beobachterklassen:

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

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

Jeder Beobachter verfügt über eine update-Methode, die aufgerufen wird, wenn er benachrichtigt wird.

Verwende das Beobachter-Muster:

# 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!")

Erstelle 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}")

# Aktien-Tracker verwenden
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

Wichtiger Punkt: Das Beobachter-Muster ermöglicht es einem Objekt, viele andere automatisch zu benachrichtigen, wenn sich etwas ändert. Das Subjekt verwaltet eine Liste von Beobachtern und ruft bei Bedarf deren update-Methode auf. Dies ist nützlich für Benachrichtigungen, Ereignissysteme und die Synchronisierung mehrerer Teile deiner Anwendung.

challenge icon

Aufgabe

Mittel

Implementiere das Observer Pattern, indem du ein System zur Wetterüberwachung erstellst. Du musst in den vorgesehenen Bereichen des Codes zwei Klassen erstellen.

Schritt 1: Erstelle die Klasse WeatherStation

Schreibe deine Klasse WeatherStation dort, wo der Kommentar darauf hinweist. Diese Klasse sollte:

  • Von der Klasse Subject erben (verwende class WeatherStation(Subject):)
  • Initialisiert werden mit:
    • Rufe den Konstruktor der übergeordneten Klasse mit super().__init__() auf
    • Setze die Anfangstemperatur mithilfe eines Attributs mit einfachem Unterstrich self._temperature auf 0 (Pythons Konvention für ein internes Attribut)
  • Implementiere <strong>set_temperature(self, temperature)</strong>:
    • Aktualisiere das interne Temperaturattribut
    • Rufe self.notify(self._temperature) auf, um alle Beobachter zu benachrichtigen
  • Implementiere <strong>get_temperature(self)</strong>:
    • Gib den aktuellen Temperaturwert zurück

Schritt 2: Erstelle die Klasse WeatherDisplay

Schreibe deine Klasse WeatherDisplay dort, wo der Kommentar darauf hinweist. Diese Klasse sollte:

  • Von der Klasse Observer erben (verwende class WeatherDisplay(Observer):)
  • Initialisiert werden mit:
    • Einen name-Parameter akzeptieren
    • Den Namen als self.name speichern
  • Implementiere <strong>update(self, temperature)</strong>:
    • Gib die Nachricht zur Temperaturaktualisierung exakt im unten gezeigten Format aus

Nachrichtenformat:

Wenn ein Display eine Temperaturaktualisierung empfängt, muss es exakt Folgendes ausgeben:

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

Beispielverwendung:

# Wetterstation und Anzeigen erstellen
station = WeatherStation()
phone_display = WeatherDisplay("Phone")
tablet_display = WeatherDisplay("Tablet")

# Anzeigen an Station anhängen
station.attach(phone_display)
station.attach(tablet_display)

# Temperatur aktualisieren – beide Anzeigen werden benachrichtigt
station.set_temperature(25.5)

# Ausgabe:
# 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 – du musst sie weder implementieren noch in deiner Klasse WeatherStation aufrufen
  • In der obigen Beispielverwendung wird station.attach(phone_display) vom Benutzer deiner Klasse aufgerufen, nicht innerhalb deiner Implementierung von WeatherStation
  • Deine Klasse WeatherStation muss nur self.notify() aufrufen, wenn sich die Temperatur ändert – die Basisklasse Subject übernimmt den Rest
  • Konzentriere dich darauf, die drei erforderlichen Methoden in WeatherStation und die zwei erforderlichen Methoden in WeatherDisplay wie oben angegeben zu implementieren

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

# Schreibe deine WeatherStation-Klasse hier

# Schreibe deine WeatherDisplay-Klasse hier

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 Objektorientierte Programmierung

Übe selbstständig: Online-Python-Compiler