Menu
CoddyTech

Observer-Muster

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

Das Observer-Muster stellt eine Eins-zu-viele-Beziehung her, 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 hat eine update-Methode, die aufgerufen wird, wenn er benachrichtigt wird.

Verwende das Beobachtermuster:

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

# Verwende 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

Kernaussage: Das Beobachtermuster ermöglicht es einem Objekt, viele andere automatisch zu benachrichtigen, wenn sich etwas ändert. Das Subjekt führt eine Liste von Beobachtern und ruft bei Bedarf deren update-Methode auf. Das ist nützlich für Benachrichtigungen, Ereignissysteme und um mehrere Teile deiner Anwendung synchron zu halten.

challenge icon

Aufgabe

Mittel

Implementiere das Observer Pattern, indem du ein Wetterüberwachungssystem erstellst. Du musst zwei Klassen in den dafür vorgesehenen Bereichen des Codes erstellen.

Schritt 1: Erstelle die Klasse WeatherStation

Schreibe deine Klasse WeatherStation an der Stelle, die im Kommentar angegeben ist. Diese Klasse sollte:

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

Schritt 2: Erstelle die Klasse WeatherDisplay

Schreibe deine Klasse WeatherDisplay an der Stelle, die im Kommentar angegeben ist. Diese Klasse sollte:

  • Von der Klasse Observer erben (verwende class WeatherDisplay(Observer):)
  • Folgendermaßen initialisiert werden:
    • Nimmt einen Parameter name entgegen
    • Speichert den Namen als self.name
  • Implementiere update(self, temperature):
    • Gib die Temperaturaktualisierungsnachricht genau im unten gezeigten Format aus

Nachrichtenformat:

Wenn eine Anzeige eine Temperaturaktualisierung erhält, muss sie genau Folgendes ausgeben:

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

Beispielverwendung:

# 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 – du musst sie weder implementieren noch in deiner Klasse WeatherStation aufrufen
  • Im obigen Beispiel wird station.attach(phone_display) vom Benutzer deiner Klasse aufgerufen, nicht innerhalb deiner WeatherStation-Implementierung
  • Deine WeatherStation muss nur self.notify() aufrufen, wenn sich die Temperatur ändert – die Basisklasse Subject kümmert sich um den Rest
  • Konzentriere dich darauf, die drei erforderlichen Methoden in WeatherStation und die zwei erforderlichen Methoden in WeatherDisplay wie oben beschrieben 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 hier deine WeatherStation-Klasse

# Schreibe hier deine 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 Objektorientierte Programmierung

Übe selbstständig: Online-Python-Compiler