Java-Entwurfsmuster (design pattern): Observer

Heute werfen wir einen Blick auf das nächste Entwurfsmuster (Java design patterns) aus der Kategorie der Verhaltensmuster (Behavioral Patterns) – Observer. Entwurfsmuster in dieser Kategorie befassen sich mit der Kommunikation(interaction) zwischen Objekten und ihrer Verantwortung (responsibility).

Was ist das Entwurfsmuster Observer?

Observer ist ein Entwurfsmuster, mit dem wir einen Mechanismus zur Entgegennahme von Nachrichten und zur Benachrichtigung aller interessierten Objekte über alle Ereignisse, die bei dem beobachteten Objekt auftreten, definieren können.

Welches Problem wird mit dem Entwurfsmuster Observer gelöst?

Observer ist ein Entwurfsmuster, das das Problem der Verfolgung einer Zustandsänderung eines Objekts löst, so dass alle abhängigen Objekte (Beobachter) automatisch benachrichtigt und aktualisiert werden, wenn eine Änderung im Objekt auftritt. Dieses Muster ermöglicht es, schwache Verbindungen zwischen dem Subjekt (dem Objekt, das seinen Zustand ändert) und den Beobachtern (den Objekten, die über die Änderung informiert werden möchten) herzustellen. Das beobachtete Objekt – Publisher geht durch Ereignisse, die für andere Objekte von Interesse sind. Diese Ereignisse treten ein, wenn es seinen Zustand ändert oder eine Aktion ausführt. Publisher verfügen über eine Abonnement-Infrastruktur, die es neuenAbonnenten ermöglicht, der Liste beizutreten und bestehenden Abonnenten, die Liste zu verlassen. Wenn ein neues Ereignis eintritt, durchläuft der Herausgeber die Abonnentenliste und ruft bei jedem Abonnentenobjekt die in der Abonnentenschnittstelle deklarierte Benachrichtigungsmethode auf. Die Teilnehmerschnittstelle besteht in den meisten Fällen aus einer einzigen Aktualisierungsmethode. Die Methode kann mehrere Parameter haben, die es dem Herausgeber ermöglichen, detailliertere Informationen über das Ereignis zusammen mit der Aktualisierung zu melden. Bestimmte Abonnenten ergreifen ihre eigenen Maßnahmen als Reaktion auf die Mitteilungen des Herausgebers. Alle diese Klassen müssen dieselbe Schnittstelle implementieren, so dass der Herausgeber nicht direkt mit bestimmten Klassen verbunden ist. Abonnenten benötigen in der Regel kontextbezogene Informationen, um die Aktualisierung korrekt zu verarbeiten. Der Client erstellt Verleger- und Abonnentenobjekte getrennt und registriert dann Abonnenten für Verlegeraktualisierungen.

Ein Beispiel für eine Observer-Implementierung in Java.

Um die praktische Anwendung des Observer-Entwurfsmusters zu demonstrieren, erstellen wir eine einfache Simulation eines YouTube-Kanals. Hier können sich Benutzer (Abonnenten) für Benachrichtigungen über neue Videos auf dem Kanal anmelden oder ihr Abonnement kündigen. IOdoberatel.java

package designpatterns;

public interface IOdoberatel {
    void aktualizovat(String sprava);
}

Die Schnittstelle IOdoberatel definiert die Aktualisierungsmethode, die von bestimmten Abonnenten implementiert wird. Es wird zur Aktualisierung bei neuen Inhalten verwendet. YouTubeUser.java

package designpatterns;

public class YouTubePouzivatel implements IOdoberatel {
    private String meno;

    public YouTubePouzivatel(String meno) {
        this.meno = meno;
    }

    @Override
    public void aktualizovat(String videoTitul) {
        System.out.println(meno + " dostal/a notifikáciu o novom videu: " + videoTi-tul);
    }

    @Override
    public String toString() {
        return meno;
    }
}
 Trieda YouTubePouzivatel reprezentuje konkrétneho používateľa, ktorý môže prijímať notifikácie o nových videách.

IYoutubeKanal.java

package designpatterns;

public interface IYoutubeKanal {
    void odoberat(IOdoberatel odoberatel);
    void zrusitOdber(IOdoberatel odoberatel);
    void upozornitOdoberatelov(String videoTitul);
}

Die Schnittstelle IYoutubeKanal definiert die Methoden subscribe, deleteSubscriber und notifySubscriber, die ein bestimmter YouTube-Kanal implementieren wird. Sie wird zur Verwaltung der Abonnenten verwendet. YouTubeKanal.java

package designpatterns;

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

public class YouTubeKanal implements IYoutubeKanal {
    private List<IOdoberatel> odoberatelia = new ArrayList<>();
    private String nazovKanala;

    public YouTubeKanal(String nazovKanala) {
        this.nazovKanala = nazovKanala;
    }

    @Override
    public void odoberat(IOdoberatel odoberatel) {
        odoberatelia.add(odoberatel);
        System.out.println(odoberatel + " odoberá " + nazovKanala);
    }

    @Override
    public void zrusitOdber(IOdoberatel odoberatel) {
        odoberatelia.remove(odoberatel);
        System.out.println(odoberatel + " odhlásil/a odber " + nazovKanala);
    }

    @Override
    public void upozornitOdoberatelov(String videoTitul) {
        for(IOdoberatel odoberatel : odoberatelia) {
            odoberatel.aktualizovat(videoTitul);
        }
    }

    public void nahratNoveVideo(String videoTitul) {
        System.out.println("Nové video bolo pridané: " + videoTitul);
        upozornitOdoberatelov(videoTitul);
    }
}

Die Klasse YouTubeKanal repräsentiert einen bestimmten YouTube-Kanal, der Abonnenten abonnieren und abbestellen kann und sie über neue Videos benachrichtigt. Main.java

import designpatterns.IOdoberatel;
import designpatterns.IYoutubeKanal;
import designpatterns.YouTubeKanal;
import designpatterns.YouTubePouzivatel;

public class Main {
    public static void main(String[] args) {
        // Vytvorenie YouTube kanalu
        YouTubeKanal youtubeKanal = new YouTubeKanal("[Programovanie v Jave]");

        // Vytvorenie odoberatelov (subscribers)
        IOdoberatel odoberatel1 = new YouTubePouzivatel("Subscriber1");
        IOdoberatel odoberatel2 = new YouTubePouzivatel("Subscriber2");

        // Nastavenie odberov YouTube kanala
        youtubeKanal.odoberat(odoberatel1);
        youtubeKanal.odoberat(odoberatel2);

        // Pridanie noveho videa, vsetci odoberatelia dostanu upozornenie
        youtubeKanal.nahratNoveVideo("Navrhove vzory v Jave");

        // Odoberatel 1 odhlasi odber
        youtubeKanal.zrusitOdber(odoberatel1);

        // Pridanie dalsieho videa, notifikaciu dostatne len Odoberatel 2
        youtubeKanal.nahratNoveVideo("Java SDK 21");
    }
}

Die Klasse Main simuliert den Betrieb eines einzelnen YouTube-Kanals, auf dem Benutzer (Abonnenten) ein Abonnement abschließen können und alle Abonnenten benachrichtigt werden, wenn ein neues Video hinzugefügt wird. Ebenso ist zu sehen, dass der Benutzer nach dem Abmelden vom Abonnement keine Benachrichtigungen über neue Inhalte mehr erhält. Die Ausgabe dieses Beispiels ist:  

Die Ausgabe des Beispiels für das Entwurfsmuster Observer.

Zusammenfassung

Das Observer Entwurfsmuster wird in Systemen verwendet, die Ereignisse verarbeiten, z.B. in GUI-Komponenten (Mausklick auf eine Schaltfläche), aber sie sind überall dort nützlich, wo wir flexibel auf eine Änderung am beobachteten Objekt reagieren wollen. Wir haben die Dateien mit dem obigen Beispiel in Form von Code vorbereitet, den du direkt in Java ausführen kannst. Lade den Java Observer-Code hier herunter. Wenn du auf der Suche nach einem Job sind und ein Java-Programmierer bist , informiere dich über unsere Mitarbeitervorteile und reagiere auf unsere aktuellen Stellenausschreibungen.  

Über den Autor

Jozef Wagner

Java Developer Senior

Viac ako 10 rokov programujem v Jave, momentálne pracujem v msg life Slovakia ako Java programátor senior a pomáham zákazníkom implementovať ich požiadavky do poistného softvéru Life Factory. Vo voľnom čase si rád oddýchnem v lese, prípadne si zahrám nejakú dobrú počítačovú hru.

Informieren Sie uns über sich