Das Beobachtermuster ist ein Verhaltensentwurfsmuster. Die Verwendung des Observer-Musters erfolgt, wenn Sie am Zustand eines Objekts interessiert sind und bei jeder Änderung benachrichtigt werden möchten. Im Beobachtermuster wird das Objekt, das den Zustand eines anderen Objekts beobachtet, als Beobachter bezeichnet, und das beobachtete Objekt wird als Subjekt bezeichnet. Gemäß den GoF-Regeln ist die Absicht des Observer-Musters:
Kopieren Sie den Codecode wie folgt:
Definieren Sie eine Eins-zu-Viele-Abhängigkeitsbeziehung zwischen Objekten. Wenn sich der Status eines Objekts ändert, werden andere verwandte Objekte benachrichtigt und automatisch aktualisiert.
Subjekte enthalten Beobachter, die benachrichtigt werden müssen, wenn sich ihr Zustand ändert. Daher sollte es Beobachtern Methoden zur Verfügung stellen, mit denen sie sich registrieren und abmelden können. Wenn sich das (beobachtete) Subjekt ändert, muss auch eine Methode zur Benachrichtigung aller Beobachter enthalten sein. Wenn Sie Beobachter benachrichtigen, können Sie Updates pushen oder eine andere Methode zum Abrufen von Updates bereitstellen.
Beobachter sollten über eine Methode verfügen, die das Beobachterobjekt festlegt und vom Beobachteten verwendet werden kann, um es über Aktualisierungen zu informieren.
JAVA bietet integrierte Möglichkeiten zur Implementierung des Beobachtermusters, der Schnittstellen java.util.Observable und java.util.Observer. Allerdings sind sie nicht sehr weit verbreitet. Da diese Implementierung zu einfach ist, möchten wir in den meisten Fällen nicht, dass die letzte erweiterte Klasse nur das Beobachtermuster implementiert, da JAVA-Klassen nicht mehrfach erben können.
Der Nachrichtendienst Java Messages Service (JMS) verwendet den Beobachtermodus und den Befehlsmodus, um die Veröffentlichung und das Abonnement von Daten zwischen verschiedenen Programmen zu realisieren.
Das MVC-Framework zur Modellansichtssteuerung verwendet ebenfalls das Beobachtermuster und behandelt das Modell als Beobachtetes und die Ansicht als Beobachter. Ansichten können sich beim Modell registrieren, um Änderungen am Modell zu empfangen.
Beispiel für ein Beobachtermuster
In diesem Beispiel führen wir eine einfache Themendiskussion durch und Beobachter können sich für dieses Thema registrieren. Alle Änderungen, die sich aus der Einreichung von Inhalten zu diesem Thema ergeben, werden allen registrierten Beobachtern mitgeteilt.
Basierend auf den Anforderungen der Beobachter des Subjekts besteht dies darin, eine grundlegende Subjektschnittstelle zu implementieren. Diese Schnittstelle spezifiziert eine Reihe spezifischer Methoden, die in der spezifischen Klasse implementiert werden müssen, die anschließend die Schnittstelle implementiert.
Kopieren Sie den Codecode wie folgt:
Paket com.journaldev.design.observer;
öffentliche Schnittstelle Betreff {
//Methoden zum Registrieren und Abmelden von Beobachtern
öffentliches Nichtigkeitsregister (Observer obj);
public void unregister(Observer obj);
//Methode zur Benachrichtigung von Beobachtern über Änderungen
public void notifyObservers();
//Methode zum Abrufen von Aktualisierungen vom Betreff
öffentliches Objekt getUpdate(Observer obj);
}
Erstellen Sie nun einen zugehörigen Beobachter. Es benötigt eine Methode, um das Subjekt einem Beobachter zuzuordnen. Zusätzliche Methoden können Benachrichtigungen über Betreffänderungen akzeptieren.
Kopieren Sie den Codecode wie folgt:
Paket com.journaldev.design.observer;
öffentliche Schnittstelle Observer {
//Methode zum Aktualisieren des Beobachters, verwendet vom Subjekt
public void update();
//mit dem zu beobachtenden Thema anhängen
public void setSubject(Subject sub);
}
Diese Verbindung wurde hergestellt. Setzen Sie nun das konkrete Thema um.
Kopieren Sie den Codecode wie folgt:
Paket com.journaldev.design.observer;
import java.util.ArrayList;
java.util.List importieren;
Die öffentliche Klasse MyTopic implementiert Subject {
private List<Observer>-Beobachter;
private String-Nachricht;
privater boolescher Wert geändert;
privates finales Objekt MUTEX= new Object();
public MyTopic(){
this.observers=new ArrayList<>();
}
@Override
öffentliches Leereregister(Observer obj) {
if(obj == null) throw new NullPointerException("Null Observer");
if(!observers.contains(obj)) Observers.add(obj);
}
@Override
public void unregister(Observer obj) {
Observer.remove(obj);
}
@Override
public void notifyObservers() {
List<Observer> ObserversLocal = null;
// Synchronisierung wird verwendet, um sicherzustellen, dass nach dem Empfang der Nachricht registrierte Beobachter nicht benachrichtigt werden
synchronisiert (MUTEX) {
wenn (!geändert)
zurückkehren;
ObserversLocal = new ArrayList<>(this.observers);
this.changed=false;
}
for (Observer obj : ObserverLocal) {
obj.update();
}
}
@Override
öffentliches Objekt getUpdate(Observer obj) {
gib diese Nachricht zurück;
}
//Methode zum Posten einer Nachricht zum Thema
public void postMessage(String msg){
System.out.println("Nachricht gepostet zum Thema:"+msg);
this.message=msg;
this.changed=true;
notifyObservers();
}
}
Die Implementierung der Registrierung und Aufhebung der Registrierung von Beobachtermethoden ist sehr einfach. Die zusätzliche Methode postMessage() wird vom Client verwendet, um eine Zeichenfolgennachricht an dieses Thema zu senden. Beachten Sie, dass boolesche Variablen verwendet werden, um Änderungen im Themenstatus zu verfolgen und Beobachter über solche Änderungen zu benachrichtigen. Diese Variable ist notwendig, denn wenn es keine Aktualisierung gibt, aber jemand die notifyObservers()-Methode aufruft, kann er keine Fehlerbenachrichtigungsinformationen an die Beobachter senden.
Darüber hinaus ist zu beachten, dass in notifyObservers() die Synchronisierung verwendet wird, um sicherzustellen, dass Benachrichtigungen nur an registrierte Beobachter gesendet werden können, bevor die Nachricht im Thema veröffentlicht wird.
Hier ist die Implementierung des Beobachters. Sie werden sich immer auf das Subjektobjekt konzentrieren.
Kopieren Sie den Codecode wie folgt:
Paket com.journaldev.design.observer;
Die öffentliche Klasse MyTopicSubscriber implementiert Observer {
privater String-Name;
privates Fachthema;
public MyTopicSubscriber(String nm){
this.name=nm;
}
@Override
public void update() {
String msg = (String) topic.getUpdate(this);
if(msg==null){
System.out.println(name+":: Keine neue Nachricht");
}anders
System.out.println(name+":: Consuming message::"+msg);
}
@Override
public void setSubject(Subject sub) {
this.topic=sub;
}
}
Beachten Sie, dass die Implementierung der update()-Methode getUpdate() des Beobachters verwendet, um aktualisierte Nachrichten zu verarbeiten. Die Übergabe der Nachricht als Parameter an die update()-Methode sollte hier vermieden werden.
Hier ist ein einfaches Testprogramm, um die Implementierung der Themenklasse zu überprüfen.
Kopieren Sie den Codecode wie folgt:
Paket com.journaldev.design.observer;
öffentliche Klasse ObserverPatternTest {
public static void main(String[] args) {
//Betreff erstellen
MyTopic topic = new MyTopic();
//Beobachter erstellen
Observer obj1 = new MyTopicSubscriber("Obj1");
Observer obj2 = new MyTopicSubscriber("Obj2");
Observer obj3 = new MyTopicSubscriber("Obj3");
// Beobachter zum Thema registrieren
topic.register(obj1);
topic.register(obj2);
topic.register(obj3);
//Beobachter an Subjekt anhängen
obj1.setSubject(topic);
obj2.setSubject(topic);
obj3.setSubject(topic);
//Überprüfen Sie, ob ein Update verfügbar ist
obj1.update();
//Jetzt Nachricht an Betreff senden
topic.postMessage("Neue Nachricht");
}
}
Hier ist die obige Ausgabe:
Kopieren Sie den Codecode wie folgt:
Obj1:: Keine neue Nachricht
Nachricht zum Thema: Neue Nachricht gepostet
Obj1::Consuming message::New Message
Obj2::Consuming message::New Message
Obj3::Consuming message::New Message</pre>
UML-Diagramm des Observer-Musters
Das Beobachtermuster wird auch Publish-Subscribe-Muster genannt. Einige spezifische Anwendungen in JAVA sind wie folgt:
1.java.util.EventListener in Swing
2.javax.servlet.http.HttpSessionBindingListener
3.javax.servlet.http.HttpSessionAttributeListener
Bei den oben genannten handelt es sich ausschließlich um Beobachtermodi. Ich hoffe, es gefällt euch schon. Teilen Sie Ihre Gefühle in den Kommentaren mit oder teilen Sie sie bitte mit anderen.