Das Beispiel im ersten Abschnitt „Den JAVA-Ereignisverarbeitungsmechanismus von Grund auf verstehen (1)“ ist zu einfach, so einfach, dass jeder das Gefühl hat, dass ein solcher Code einfach nutzlos ist. Aber es gibt keine Möglichkeit, wir müssen diesen nutzlosen Code weiter schreiben und dann zur nächsten Stufe wirklich nützlichen Codes übergehen.
1: Ein erster Blick auf das ereignisgesteuerte Modell
Wir möchten sagen, dass das ereignisgesteuerte Modell eine aktualisierte Version des Beobachtermusters ist, dann wir über die entsprechende Beziehung sprechen müssen:
Der Beobachter entspricht dem Zuhörer (Schüler)
Das Beobachtete entspricht der Ereignisquelle (Lehrer)
Die Ereignisquelle generiert ein Ereignis, und das Ereignis hat eine Ereignisquelle, und der Listener wartet auf Ereignisse. Freunde, die gerne über Dinge reden, sagen vielleicht: „Hey, was sind erzeugende Ereignisse, überwachende Ereignisse und was genau sind Ereignisse?“
Keine Panik, wenn wir über Dinge im Code sprechen, ist das Ereignis eine Klasse und die Ereignisquelle ist ebenfalls eine Klasse. Dabei gibt es vier Kategorien: Ereignisquelle (d. h. Lehrer, d. h. Beobachter), Ereignis (eine Klasse, siehe unten, normalerweise enden wir mit Event oder EventObject), Listener-Schnittstelle, spezifischer Listener (d. h. Schüler, d. h. Beobachter).
Wie im ersten Abschnitt unseres vorherigen Artikels erwähnt, gibt es im JDK natürlich vorgefertigte Event-Modellklassen. Wir können sie uns auch einzeln ansehen.
Schauen Sie sich zunächst den Zuhörer an (das heißt den Schüler, den Beobachter, finden Sie es nicht störend, ich lasse immer wieder Klammern weg, um Sie daran zu erinnern, dies soll allen einen tieferen Eindruck vermitteln),
package java.util;
/**
* Eine Tagging-Schnittstelle, die alle Ereignis-Listener-Schnittstellen erweitern müssen.
* @seit JDK1.1
*/
public interface EventListener {
}
Es könnte nicht Einfacher geht es nicht, oder? Es gibt nicht einmal eine deklarierte Methode, welchen Sinn hat sie also? Denken Sie an das objektorientierte Upcasting, das bedeutet, allen Anrufern mitzuteilen, dass ich ein Zuhörer bin.
Sehen wir uns das Ereignis an, also die Klasse am Ende von Event oder EventObject, die die getSource-Methode enthält, die die Ereignisquelle (also den Lehrer, den Beobachter) zurückgibt,
Alte Regeln, geben wir der Klasse Diagramm zuerst:Paket java.util;
/**
*
* Die Stammklasse, von der alle Ereigniszustandsobjekte abgeleitet werden sollen.
*
* Alle Ereignisse werden mit einem Verweis auf das Objekt erstellt, dem „ Quelle",
* das wird logischerweise als das Objekt angesehen, auf dem das betreffende Ereignis
* ursprünglich aufgetreten ist.
*
* @seit JDK1.1
*/öffentliche Klasse EventObject implementiert java.io.Serializable {
private static final long serialVersionUID = 5516075349620653480L;
/**
* Das Objekt, auf dem das Ereignis ursprünglich aufgetreten ist.
*/
protected transient Object source;/**
/**
* Konstruiert ein prototypisches Ereignis.
*
* @param Quelle Das Objekt, auf dem das Ereignis ursprünglich aufgetreten ist.
* @Exception IllegalArgumentException , wenn die Quelle null ist.
*/
public EventObject(Object source) {
if (source == null)
* Das Objekt, auf dem das Ereignis ursprünglich aufgetreten ist.
* @return Das Objekt, auf dem das Ereignis ursprünglich aufgetreten ist.
**/
public String toString() {
return getClass().getName() + "[source=" + source + "]";
}
}
Dies Die Klassen sind auch sehr einfach. Wenn die oberen Klassen und Ergebnisse im Beobachtermuster viel Logik und Methoden haben, kann man in den oberen Klassen und Schnittstellen kaum etwas sehen das ereignisgesteuerte Modell. Das ist richtig,
Im ereignisgesteuerten Modell haben die Designer von JDK die Abstraktion auf höchster Ebene durchgeführt, die darin besteht, die Oberschicht nur darstellen zu lassen: Ich bin ein Ereignis (das die Ereignisquelle enthält). , oder, ich Es ist ein Zuhörer!
2: Die ereignisgesteuerte Modellversion der vom Lehrer zugewiesenen Aufgabe
Dann implementiert der Code es:
Beobachterschnittstelle (Student). Da es im ereignisgesteuerten Modell nur eine Schnittstelle ohne Methoden gibt, EventListener, können wir zunächst eine eigene Schnittstelle implementieren. Um mit dem Code im vorherigen Artikel übereinzustimmen, wird der Name der Methode, die wir in dieser Schnittstelle deklariert haben, auch als Update bezeichnet. Beachten Sie, dass wir diesen Namen natürlich nicht verwenden oder je nach unseren Geschäftsanforderungen sogar andere Methodendeklarationen hinzufügen können.
Paket com.zuikc.events;
java.util.Observable importieren;
öffentliche Schnittstelle HomeworkListener erweitert java.util.EventListener {
Public void update(HomeworkEventObject o, Object arg);
}
Dann implementieren Sie die Beobachterklasse (Student) wie folgt:
Paket com.zuikc . events;
public class Student implementiert HomeworkListener{
private String name;
public Student(String name){
this.name = name;
}
@Override
public void update(HomeworkEventObject o, Object arg) {
Teacher teacher = o.getTeacher();
System.out.printf("Schüler %s hat beobachtet (tatsächlich wurde er benachrichtigt), dass %s eine Aufgabe zugewiesen hat "%s" n", this.name, teacher.getName(), arg);
}}
Gibt es im Vergleich zum vorherigen Artikel Änderungen? ?
Dann implementieren Sie die Event-Unterklasse wie folgt:
private String name;package com.zuikc.events;
public class HomeworkEventObject erweitert java.util.EventObject {
public HomeworkEventObject (Objektquelle) {
import java.util .*;public class Teacher {
super (Quelle); ( ){
return (Teacher) super.getSource(); Kapselt die getSource-Methode der übergeordneten Klasse EventObject, um die Ereignisquelle abzurufen. Theoretisch ist es für uns auch möglich, die getSource-Methode der übergeordneten Klasse zu verwenden, aber eine erneute Kapselung in der Unterklasse macht sie besser lesbar.
Dann gibt es noch unsere Lehrerklasse, die die Ereignisquelle ist, wie folgt:
package com.zuikc.events;
private List
* Die Lehrerklasse muss ihren eigenen Listener (Schüler) pflegen Liste, warum?
* Im Beobachtermuster ist der Lehrer der Beobachter, geerbt von java.util.Observable, Observable enthält diese Liste* Jetzt haben wir diese Liste nicht, also müssen wir selbst eine erstellen* /
private SethomeworkListenerList; public String getName() { return this.name;
public void setHomework (String homework) {
}
public Teacher(String name) {
this.name = name;
this.homeworks = new ArrayList();
this.homeworkListenerList = new HashSet();
}System.out.printf("%s zugewiesene Hausaufgabe %s n", this.name, homework);
listener.update(event, homework);
homeworks.add(homework);
HomeworkEventObject event = new HomeworkEventObject( this ); for (HomeworkListener listener : homeworkListenerList) {}
}
public void addObserver(HomeworkListener homeworkListener){
homeworkListenerList.add(homeworkListener);
}}
Dieser Kurs ist etwas länger Es gibt also ein paar erwähnenswerte Stellen:
Der erste Punkt ist, dass Teacher keine übergeordnete Klasse hat, da die Ereignisquelle im Ereignis in HomeworkEventObject gekapselt ist. Daran ist nichts auszusetzen, die Geschäftsobjekte sind vom Framework-Code isoliert und die Entkopplung ist sehr gut. Aus diesem Grund müssen wir selbst eine Liste der Schüler verwalten, daher haben wir die Variable homeworkListenerList gesehen.
Zweitens rufen wir im Beobachtermodus direkt die notifyObservers von Observable auf, um das Beobachtete zu benachrichtigen. Jetzt können wir uns nur noch auf uns selbst verlassen, also haben wir diesen Code gesehen,
für (HomeworkListener-Listener: homeworkListenerList) {
listener.update(event, homework);
}
Das ist überhaupt kein Problem:
package com.zuikc.events;
import java.util.EventListener;
public class Client {
public static void main(String[ ] args) {
Student student1= neuer Student("Zhang San");
Student student2 = neuer Student("李思");
Lehrer teacher1 = neuer Lehrer("zuikc");
teacher1.addObserver (student1);
teacher1.addObserver(student2);
teacher1.setHomework("Ereignismechanismus Hausaufgaben für den zweiten Tag");
}}
Die Ergebnisse sind wie folgt:
Aus Sicht des Kunden haben wir fast überhaupt nichts geändert. Es ist genau das Gleiche wie der Kundencode im Beobachtermodus, aber intern. Als Implementierungsmechanismus verwenden wir den Ereignismechanismus.
Lassen Sie uns nun die Unterschiede zwischen dem Beobachtermuster und dem ereignisgesteuerten Modell zusammenfassen:
1: Die Ereignisquelle erbt kein Muster oder die übergeordnete Klasse des Modells selbst mehr, wodurch das Modell vollständig transformiert wird Geschäft Der Code ist entkoppelt;
2: Im Ereignismodell muss jeder Listener (Beobachter) eine eigene Schnittstelle implementieren. Genau, schauen Sie sich unsere Mausereignisse an. Die Untertabelle enthält Klick-, Doppelklick-, Verschiebeereignisse usw., die jeweils die Flexibilität des Codes erhöhen.
Auf jeden Fall verwenden wir eine Reihe von Ereignissen small Der weiße Code implementiert ein Beispiel für ein ereignisgesteuertes Modell, obwohl er keinen praktischen Nutzen hat, aber auch das Prinzip erklärt. Im nächsten Abschnitt werden wir uns einen etwas komplexen und scheinbar nützlichen Code ansehen.
Das obige ist der detaillierte Inhalt vonVerstehen Sie den JAVA-Ereignisbehandlungsmechanismus von Grund auf. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!