Menu
Coddy logo textTech

Observer-Muster

Teil des Abschnitts Objektorientierte Programmierung der Java-Journey von Coddy. Lektion 68 von 87.

Das Observer Pattern ist ein Verhaltensentwurfsmuster, das eine Eins-zu-viele-Beziehung zwischen Objekten herstellt. Wenn ein Objekt (das Subjekt) seinen Zustand ändert, werden alle seine abhängigen Objekte (die Beobachter) automatisch benachrichtigt und aktualisiert. Stell es dir wie ein Newsletter-Abonnement vor: Abonnenten erhalten Updates, sobald neue Inhalte veröffentlicht werden.

Das Muster umfasst zwei Hauptkomponenten: ein Subjekt, das eine Liste von Beobachtern verwaltet und sie über Änderungen benachrichtigt, sowie Beobachter, die eine Aktualisierungsmethode definieren, um auf Benachrichtigungen zu reagieren:

import java.util.ArrayList;
import java.util.List;

interface Observer {
    void update(String message);
}

class NewsPublisher {
    private List<Observer> subscribers = new ArrayList<>();
    
    public void subscribe(Observer observer) {
        subscribers.add(observer);
    }
    
    public void unsubscribe(Observer observer) {
        subscribers.remove(observer);
    }
    
    public void publish(String news) {
        for (Observer subscriber : subscribers) {
            subscriber.update(news);
        }
    }
}

class EmailSubscriber implements Observer {
    private String email;
    
    public EmailSubscriber(String email) {
        this.email = email;
    }
    
    public void update(String message) {
        System.out.println("Email to " + email + ": " + message);
    }
}

Wenn der Herausgeber Nachrichten veröffentlicht, werden alle Abonnenten automatisch benachrichtigt:

NewsPublisher publisher = new NewsPublisher();
publisher.subscribe(new EmailSubscriber("alice@mail.com"));
publisher.subscribe(new EmailSubscriber("bob@mail.com"));

publisher.publish("Breaking news!");
// Ausgabe:
// E-Mail an alice@mail.com: Breaking news!
// E-Mail an bob@mail.com: Breaking news!

Das Observer-Muster fördert eine lose Kopplung: Das Subjekt muss die konkreten Klassen seiner Beobachter nicht kennen, sondern nur wissen, dass sie die Schnittstelle Observer implementieren. Dadurch lassen sich neue Beobachtertypen einfach hinzufügen, ohne das Subjekt zu ändern.

challenge icon

Aufgabe

Einfach

Erstellen wir ein Aktienkurs-Benachrichtigungssystem mithilfe des Beobachter-Musters! Du erstellst ein System, in dem ein Aktienticker mehrere Investoren benachrichtigt, sobald sich der Aktienkurs ändert, sodass jeder Investor auf seine eigene Weise auf Kursaktualisierungen reagieren kann.

Du organisierst deinen Code auf vier Dateien verteilt:

  • Observer.java: Definiere das Observer-Interface, das alle Investoren implementieren werden. Es sollte eine einzelne Methode update(String stockName, double price) deklarieren, die Beobachter verwenden, um Benachrichtigungen über Kursänderungen zu erhalten.
  • StockTicker.java: Erstelle die Subjektklasse, die eine Liste von Beobachtern verwaltet und sie über Kursänderungen benachrichtigt. Dein StockTicker sollte Folgendes enthalten:

    Ein privates String-Feld für den Namen der Aktie (wird über den Konstruktor festgelegt).

    Ein privates double-Feld für den aktuellen Kurs (anfangs 0).

    Eine private Liste zum Speichern abonnierter Beobachter.

    Eine subscribe(Observer observer)-Methode, die einen Beobachter zur Liste hinzufügt.

    Eine unsubscribe(Observer observer)-Methode, die einen Beobachter aus der Liste entfernt.

    Eine setPrice(double price)-Methode, die den Kurs aktualisiert und anschließend alle Beobachter benachrichtigt, indem sie deren update-Methode mit dem Namen der Aktie und dem neuen Kurs aufruft.

  • Investors.java: Erstelle zwei verschiedene Arten von Investoren, die das Observer-Interface implementieren:

    DayTrader – besitzt ein privates Namensfeld, das über den Konstruktor festgelegt wird. Bei einer Aktualisierung gibt es [name] received alert: [stockName] is now $[price] - Making quick trade! aus.

    LongTermInvestor – besitzt ein privates Namensfeld, das über den Konstruktor festgelegt wird. Bei einer Aktualisierung gibt es [name] received alert: [stockName] is now $[price] - Holding steady. aus.

    Formatiere den Kurs mit zwei Dezimalstellen.

  • Main.java: Führe dein Beobachtersystem zusammen! Du erhältst drei Eingaben: den Namen der Aktie (String), die erste Kursaktualisierung (double) und die zweite Kursaktualisierung (double).

    Erstelle einen StockTicker mit dem angegebenen Aktiennamen. Erstelle einen DayTrader mit dem Namen "Alice" und einen LongTermInvestor mit dem Namen "Bob", und abonniere beide beim Ticker.

    Setze den Kurs auf den ersten Eingabewert (alle Beobachter werden benachrichtigt). Entferne dann Alice. Setze schließlich den Kurs auf den zweiten Eingabewert (diesmal sollte nur Bob benachrichtigt werden).

Du erhältst drei Eingaben in dieser Reihenfolge: Aktienname (String), erster Kurs (double), zweiter Kurs (double).

Diese Herausforderung veranschaulicht die Leistungsfähigkeit des Beobachter-Musters: Der StockTicker weiß nichts über die konkreten Investorentypen. Er weiß lediglich, dass sie Observer implementieren. Wenn du Alice abbestellst, erhält sie keine Aktualisierungen mehr, während Bob weiterhin benachrichtigt wird. Diese lose Kopplung macht es einfach, neue Investorentypen hinzuzufügen, ohne den Ticker zu ändern!

Probier es selbst

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // Eingaben lesen
        String stockName = scanner.nextLine();
        double firstPrice = scanner.nextDouble();
        double secondPrice = scanner.nextDouble();
        
        // TODO: Erstelle einen StockTicker mit dem gegebenen Aktiennamen
        
        // TODO: Erstelle einen DayTrader namens "Alice"
        
        // TODO: Erstelle einen LongTermInvestor namens "Bob"
        
        // TODO: Abonniere sowohl Alice als auch Bob beim Ticker
        
        // TODO: Setze den Preis auf firstPrice (beide Beobachter werden benachrichtigt)
        
        // TODO: Melde Alice ab
        
        // TODO: Setze den Preis auf secondPrice (nur Bob wird benachrichtigt)
        
        scanner.close();
    }
}
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-Java-Compiler