Praktische Analyse des Beobachter-Musters

Im Allgemeinen gibt es in der objektorientierten Analyse und Design drei Mechanismen zur Ereignisbehandlung. Neben dem gewöhnlichen Funktionsaufruf werden häufig Callback-Funktionen verwendet. In J2EE wird außerdem ein ereignisbasiertes Listener-Konzept bereitgestellt. Recherchieren Sie bitte und analysieren Sie den Mechanismus von Action und ActionListener. Erstellen Sie ein Analysebeispiel.

Zunächst das Beobachter-Muster verstehen.

Das Beobachter-Muster (Observer Pattern)

Beobachter in der realen Welt

Das Beobachter-Muster wird auch als Publish-Subscribe-Muster bezeichnet. Ein Beispiel ist RSS (der Vorläufer von WeChat-Push). Wenn der Autor eines Blogs (das beobachtete Subjekt) einen neuen Artikel veröffentlicht, erhalten die Abonnenten (die Beobachter) in ihrem Feed-Reader automatisch das Update. Dieses Veröffentlichungs-Abonnement-Schema nennen wir das Beobachter-Muster.

Das Beobachter-Muster

Die Beschreibung des Beobachter-Musters durch die Gang Of Four:

  • Absicht

    Definiere eine Eins-zu-viele-Abhängigkeit zwischen Objekten, sodass alle abhängigen Objekte benachrichtigt und automatisch aktualisiert werden, wenn sich der Zustand eines Objekts ändert.

  • Alias

    Dependents, Publish-Subscribe

  • Motivation

    Eine häufige Nebenwirkung der Aufteilung eines Systems in eine Reihe zusammenarbeitender Klassen ist die Notwendigkeit, die Konsistenz zwischen den zusammengehörigen Objekten aufrechtzuerhalten. Wir möchten nicht, dass die Klassen eng gekoppelt sind, um Konsistenz zu gewährleisten, da dies ihre Wiederverwendbarkeit verringert.

…

  • Beteiligte

    • Subjekt (Ziel)

      Das Subjekt kennt seine Beobachter. Es kann beliebig viele Beobachter geben, die dasselbe Subjekt beobachten.

      Bietet eine Schnittstelle zum Registrieren und Entfernen von Beobachterobjekten.

    • Beobachter (Observer)

      Definiert eine Aktualisierungsschnittstelle für Objekte, die benachrichtigt werden müssen, wenn sich das Subjekt ändert.

    • KonkretesSubjekt (ConcreteSubject)

      Speichert den relevanten Zustand in den jeweiligen ConcreteObserver-Objekten.

      Sendet eine Benachrichtigung an alle seine Beobachter, wenn sich sein Zustand ändert.

    • KonkreterBeobachter (ConcreteObserver)

      Verwaltet eine Referenz auf ein ConcreteSubject-Objekt.

      Speichert einen Zustand, der mit dem Zustand des Subjekts konsistent sein sollte.

      Implementiert die Aktualisierungsschnittstelle des Observers, um seinen eigenen Zustand mit dem des Subjekts konsistent zu halten.

Man kann sehen, dass das Beobachter-Muster häufig angewendet wird bei:

  • Zwei Objekten, die eine Abhängigkeitsbeziehung haben.
  • Einem Objekt, dessen Änderung gleichzeitig Änderungen in anderen Objekten erfordert.

Im Vergleich zu gewöhnlichen Funktionsaufrufen oder Callback-Funktionen ermöglicht die Verwendung des Beobachter-Musters eine kostengünstige Aufrechterhaltung der Konsistenz zwischen Objekten, **verringert den Grad der Kopplung zwischen Objekten erheblich und kann gleichzeitig einen Broadcast-Effekt erzielen, was die ersten beiden nicht können. Die Verwendung des Beobachter-Musters erhöht die Wiederverwendbarkeit des Codes erheblich.

Und Action und ActionListener in J2EE sind ein lebendiges Beispiel für das Beobachter-Muster.

Action & ActionListener in J2EE

Action & ActionListener können im MVC-Paradigma gut eingesetzt werden, um die Kopplung zwischen Model und View zu verringern.

Ein gutes Beispiel wurde gefunden, der Code ist unten dargestellt:

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JTextField;

public class Frame extends JFrame {

  ActionListener observer1 = new Observer("First Observer");
  ActionListener observer2 = new Observer("Second Observer");
  ActionListener observer3 = new Observer("Third Observer");

  public Frame(){
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    init();
  }

  private void init(){
    addChangingTextField();
    pack();
    setVisible(true);
  }

  private void addChangingTextField(){
    //Observable class TextField. each time
    //An action or event occurs the observers will be updated
    //Almost all the Swing classes has this kind of behavior
    JTextField dataTextField = new JTextField();

    // Observer registering to the observable class.
    dataTextField.addActionListener(observer1);
    dataTextField.addActionListener(observer2);
    dataTextField.addActionListener(observer3);

    add(dataTextField);
  }

  public static void main(String [] args){
  	Frame frame = new Frame();
  }
}

class Observer implements ActionListener{

  private String name;
  private String message;

  public Observer (String s){
  	name = s;
  }

  public void actionPerformed(ActionEvent e) {
    JTextField textField = (JTextField) e.getSource();
    message = textField.getText();
    JOptionPane.showMessageDialog(null,
    name + " has been confirmed about the change, Thanks!! "
    + " The Message was: " + message);
  }
}

Analyse

Die beiden Klassen übernehmen jeweils die Rolle von Action/ActionListener. frame.dataTextField bindet in der Methode addChangingTextField drei Listener (observer1, observer2, observer3). Nachdem der Text im Frame-Fenster bearbeitet wurde (Zustandsänderung), wird die Methode actionPerformed in Observer ausgelöst und der entsprechende Text angezeigt.

In diesem Beispiel fungiert frame.dataTextField als ConcreteSubject, und observer1, observer2, observer3 als ConcreteObserver. Die Schnittstellen, die sie implementieren und die die Action-/ActionListener-Methoden definieren, sind das entsprechende Subject und Observer.

Nach der Bindung der Beobachter kümmert sich das Subjekt nicht um das konkrete Verhalten der Beobachter, sondern benachrichtigt sie nur, wenn sich sein eigener Zustand ändert. Die Beobachter entscheiden dann selbst, welche Aktion sie ausführen. Daher ist diese Methode sehr elegant und der expliziten Ausführung von Funktionen oder Callback-Funktionen zur Auslösung von Aktionen deutlich überlegen. Es lohnt sich, dies zu lernen.

/Entwurfsmuster/ /Systemanalyse und -design/