Menu
Coddy logo textTech

Observer-Muster

Teil des Abschnitts Objektorientierte Programmierung der Dart-Journey von Coddy — Lektion 92 von 110.

Das Observer-Pattern stellt eine Eins-zu-viele-Beziehung zwischen Objekten her: Wenn ein Objekt (das Subjekt) seinen Zustand ändert, werden alle seine Abhängigen (Beobachter) automatisch benachrichtigt. Dies ist ideal für Szenarien wie UI-Updates, Event-Systeme oder jede Situation, in der mehrere Teile Ihrer Anwendung auf Änderungen reagieren müssen.

Das Muster umfasst zwei Schlüsselrollen: ein Subject, das eine Liste von Objekten führt und sie über Änderungen benachrichtigt, und Observers, die sich selbst registrieren und auf Aktualisierungen reagieren:

abstract class Observer {
  void update(String message);
}

class NewsAgency {
  final List<Observer> _observers = [];
  String _latestNews = '';

  void subscribe(Observer observer) {
    _observers.add(observer);
  }

  void unsubscribe(Observer observer) {
    _observers.remove(observer);
  }

  void publishNews(String news) {
    _latestNews = news;
    for (var observer in _observers) {
      observer.update(_latestNews);
    }
  }
}

class NewsChannel implements Observer {
  final String name;
  NewsChannel(this.name);

  @override
  void update(String message) {
    print('$name received: $message');
  }
}

void main() {
  var agency = NewsAgency();
  var cnn = NewsChannel('CNN');
  var bbc = NewsChannel('BBC');

  agency.subscribe(cnn);
  agency.subscribe(bbc);

  agency.publishNews('Breaking news!');
  // CNN hat empfangen: Breaking news!
  // BBC hat empfangen: Breaking news!
}

Wenn publishNews aufgerufen wird, iteriert die Agentur durch alle abonnierten Observer und ruft deren update-Methode auf. Observer können sich jederzeit an- oder abmelden, was das System flexibel und lose gekoppelt macht – das Subjekt muss die spezifischen Typen seiner Observer nicht kennen.

challenge icon

Aufgabe

Einfach

Lassen Sie uns ein Aktienkurs-Alarmsystem mit dem Observer-Muster bauen! Sie werden ein System erstellen, bei dem ein Stock-Ticker mehrere Investoren benachrichtigt, wann immer sich der Preis ändert, sodass jeder Investor auf seine eigene Weise auf Marktaktualisierungen reagieren kann.

Sie werden Ihren Code in zwei Dateien organisieren:

  • stock_system.dart: Erstellen Sie hier Ihr Observer-System:
    • Eine abstrakte Klasse Investor mit einer Methode void onPriceChange(String stockName, double price)
    • Eine Klasse DayTrader, die Investor implementiert. Sie hat ein name-Feld und ihre onPriceChange-Methode gibt aus: [name] sees [stockName] at $[price] - Making quick trade!
    • Eine Klasse LongTermInvestor, die Investor implementiert. Sie hat ein name-Feld und ihre onPriceChange-Methode gibt aus: [name] notes [stockName] at $[price] - Holding steady.
    • Eine Klasse StockTicker (das Subjekt) mit:
      • Einem String stockName-Feld
      • Einer privaten Liste zum Speichern der abonnierten Investoren
      • Einer subscribe(Investor investor)-Methode, um einen Investor hinzuzufügen
      • Einer unsubscribe(Investor investor)-Methode, um einen Investor zu entfernen
      • Einer updatePrice(double newPrice)-Methode, die alle abonnierten Investoren über den neuen Preis benachrichtigt
  • main.dart: Importieren Sie Ihr Aktiensystem und demonstrieren Sie das Observer-Muster in Aktion:
    • Erstellen Sie einen StockTicker für eine Aktie namens DART
    • Erstellen Sie einen DayTrader namens Alice und einen LongTermInvestor namens Bob
    • Abonnieren Sie beide Investoren beim Ticker
    • Aktualisieren Sie den Preis auf 150.50 (beide Investoren sollten benachrichtigt werden)
    • Geben Sie eine Leerzeile aus
    • Melden Sie Alice vom Ticker ab
    • Aktualisieren Sie den Preis auf 155.75 (jetzt sollte nur noch Bob benachrichtigt werden)

Dies zeigt, wie das Observer-Muster ein lose gekoppeltes System schafft – der StockTicker muss nicht wissen, ob er Daytrader oder langfristige Investoren benachrichtigt, er ruft einfach onPriceChange bei jedem auf, der abonniert ist!

Erwartete Ausgabe:

Alice sees DART at $150.5 - Making quick trade!
Bob notes DART at $150.5 - Holding steady.

Bob notes DART at $155.75 - Holding steady.

Spickzettel

Das Observer-Muster etabliert eine Eins-zu-viele-Beziehung, bei der ein Subjekt alle seine Beobachter benachrichtigt, wenn sich sein Zustand ändert.

Das Muster hat zwei Schlüsselrollen:

  • Subject: Verwaltet eine Liste von Beobachtern und benachrichtigt sie über Änderungen
  • Observer: Registriert sich beim Subjekt und reagiert auf Aktualisierungen

Grundlegende Implementierung:

abstract class Observer {
  void update(String message);
}

class Subject {
  final List<Observer> _observers = [];

  void subscribe(Observer observer) {
    _observers.add(observer);
  }

  void unsubscribe(Observer observer) {
    _observers.remove(observer);
  }

  void notifyObservers(String data) {
    for (var observer in _observers) {
      observer.update(data);
    }
  }
}

class ConcreteObserver implements Observer {
  final String name;
  ConcreteObserver(this.name);

  @override
  void update(String message) {
    print('$name received: $message');
  }
}

Wesentliche Vorteile:

  • Lose Kopplung zwischen Subjekt und Beobachtern
  • Beobachter können sich dynamisch an- und abmelden (subscribe/unsubscribe)
  • Das Subjekt muss die spezifischen Typen der Beobachter nicht kennen

Probier es selbst

import 'stock_system.dart';

void main() {
  // TODO: Erstelle einen StockTicker für eine Aktie namens 'DART'
  
  // TODO: Erstelle einen DayTrader namens 'Alice'
  
  // TODO: Erstelle einen LongTermInvestor namens 'Bob'
  
  // TODO: Melde beide Investoren beim ticker an
  
  // TODO: Aktualisiere den Preis auf 150.50 (beide Investoren sollten benachrichtigt werden)
  
  // TODO: Gib eine Leerzeile aus
  
  // TODO: Melde Alice vom ticker ab
  
  // TODO: Aktualisiere den Preis auf 155.75 (jetzt sollte nur Bob benachrichtigt werden)
}
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