java事件机制(订阅/消费模型)/观察者模式 : EventObject,EventListener和Source

Posted Mars-xq

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java事件机制(订阅/消费模型)/观察者模式 : EventObject,EventListener和Source相关的知识,希望对你有一定的参考价值。

参考:

java事件机制(订阅/消费模型)

使用Java标准的java.util.EventListener实现观察者-发布者设计模式

java的事件机制一般包括三个部分:EventObjectEventListenerSource

简单示例demo:

1.EventObject : 事件

java.util.EventObject是事件状态对象的基类,它封装了事件源对象以及和事件相关的信息。
所有java的事件类都需要继承该类


import java.util.EventObject;

public class MsgEvent extends EventObject 
    private static final long serialVersionUID = 1L;

    //也可以用source来传递值 这里用status来传递值
    private int status;

    public MsgEvent(Object source) 
        super(source);
    

    public MsgEvent(Object source, int status) 
        super(source);
        this.status = status;
    

    public int getStatus() 
        return status;
    

    public void setStatus(int status) 
        this.status = status;
    

2.EventListener : 监听事件

java.util.EventListener是一个标记接口,就是说该接口内是没有任何方法的。
所有事件监听器都需要实现该接口。
事件监听器注册在事件源上,当事件源的属性或状态改变的时候,调用相应监听器内的回调方法。

import java.util.EventListener;

public interface MsgListener extends EventListener 
    void handleMsg(MsgEvent event) throws Exception;


3.Source

事件源不需要实现或继承任何接口或类,它是事件最初发生的地方。
因为事件源需要注册事件监听器,所以事件源内需要有相应的盛放事件监听器的容器。

触发动作 :


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

public class MsgManager 
    static List<MsgListener> msgListeners = new ArrayList<MsgListener>();

    public static void addListener(MsgListener listener) 
        msgListeners.add(listener);
    

    public static void sendMsg(MsgEvent event) throws Exception 
        notifyListeners(event);
    

    public static void notifyListeners(MsgEvent event) throws Exception 
        for (MsgListener listener : msgListeners) 
            listener.handleMsg(event);
        
    

    public static void main(String[] args) 
        try 
            //监听器A
            MsgManager.addListener(new MsgListener() 
                public void handleMsg(MsgEvent event) throws Exception 
                    System.out.println("MsgListenerA," + event.getStatus());
                
            );

            //监听器B
            MsgManager.addListener(new MsgListener() 
                public void handleMsg(MsgEvent event) throws Exception 
                    System.out.println("MsgListenerB," + event.getStatus());
                
            );

            MsgEvent msg1 = new MsgEvent("test", 11);
            sendMsg(msg1);

            MsgEvent msg2 = new MsgEvent("test", 999);
            sendMsg(msg2);
         catch (Exception e) 
            e.printStackTrace();
        
    

执行main 效果

MsgListenerA,11
MsgListenerB,11
MsgListenerA,999
MsgListenerB,999

demo2 : java.util.Observable + java.util.Observer 的使用

参考:从零开始理解JAVA事件处理机制(1)

观察者:


import java.util.Observable;
import java.util.Observer;

/**
 * 观察者,学生
 */
public class Student implements Observer 

    private String name;

    public Student(String name) 
        this.name = name;
    

    @Override
    public void update(Observable observable, Object arg) 
        Teacher teacher = (Teacher) observable;
        System.out.printf("学生%s观察到(实际是被通知)%s布置了作业《%s》 \\n",
                this.name, teacher.getName(), arg);
    


被观察者


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

/**
 * 被观察者,教师
 */
public class Teacher extends Observable 

    private String name;
    private List<String> books;

    public String getName() 
        return this.name;
    

    public Teacher(String name) 
        this.name = name;
        books = new ArrayList<String>();
    

    public void setHomework(String homework) 
        System.out.printf("%s布置了作业%s \\n", this.name, homework);
        books.add(homework);
        setChanged();
        notifyObservers(homework);
    

客户端

public class Client 

    public static void main(String[] args) 
        Student student1 = new Student("张三");
        Student student2 = new Student("李四");
        Teacher teacher1 = new Teacher("王老师");
        teacher1.addObserver(student1);
        teacher1.addObserver(student2);
        teacher1.setHomework("事件机制第一天作业");
    
    //王老师布置了作业事件机制第一天作业 
    //学生李四观察到(实际是被通知)王老师布置了作业《事件机制第一天作业》 
    //学生张三观察到(实际是被通知)王老师布置了作业《事件机制第一天作业》 

demo3 : 自定义Observable + Observer 的使用

参考:从零开始理解JAVA事件处理机制(1)

观察者:

public interface Observer 
    void update(Observable o);

class ConcreteObserver1 implements Observer 

    public void update(Observable o) 
        System.out.println("观察者1观察到" +
                o.getClass().getSimpleName() + "发生变化");
        System.out.println("观察者1做出响应");
    

class ConcreteObserver2 implements Observer 

    public void update(Observable o) 
        System.out.println("观察者2观察到" +
                o.getClass().getSimpleName() + "发生变化");
        System.out.println("观察者2做出响应");
    

被观察者:

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

public class Observable 

    private List<Observer> observers = new ArrayList<Observer>();

    public void addObserver(Observer o) 
        observers.add(o);
    

    public void doSomething() 
        System.out.println("我是被观察者,我发生变化了");
        // 主动去通知所有的观察者
        notifyObservers();
    

    public void notifyObservers() 
        for (Observer observer : observers) 
            observer.update(this);
        
    

客户端:

public class Client 

    public static void main(String[] args) 
        Observable observable = new Observable();
        observable.addObserver(new ConcreteObserver1());
        observable.addObserver(new ConcreteObserver2());
        observable.doSomething();
    
    //我是被观察者,我发生变化了
    //观察者1观察到Observable发生变化
    //观察者1做出响应
    //观察者2观察到Observable发生变化
    //观察者2做出响应

demo4 : EventListener + EventObject : 事件机制

参考:从零开始理解JAVA事件处理机制(2)

EventListener: 观察者接口(学生)

import java.util.EventListener;

public interface HomeworkListener extends EventListener 
    void update(HomeworkEventObject eventObject, Object obj);


public class Student implements HomeworkListener 
    private final String name;

    public Student(String name) 
        this.name = name;
    

    @Override
    public void update(HomeworkEventObject eventObject, Object obj) 
        Teacher teacher = eventObject.getTeacher();
        System.out.printf("学生%s观察到(实际是被通知)%s布置了作业《%s》 \\n",
                this.name, teacher.getName(), obj);
    

EventObject:

java.util.EventObject是事件状态对象的基类,它封装了事件源对象以及和事件相关的信息。所有java的事件类都需要继承该类

import java.util.EventObject;

public class HomeworkEventObject extends EventObject 

    public HomeworkEventObject(Teacher teacher) 
        super(teacher);
    

    public Teacher getTeacher() 
        return (Teacher) super.getSource();
    


被观察者:


import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class Teacher 
    
    private final String name;
    private final List<String> homeworks;
    
    /*
     * 教师类要维护一个自己监听器(学生)的列表,为什么?
     * 在观察者模式中,教师是被观察者,
     * 继承自java.util.Observable,Observable中含了这个列表
     * 现在我们没有这个列表了,所以要自己创建一个
     */
    private final Set<HomeworkListener> homeworkListenerList;

    public String getName() 
        return this.name;
    

    public Teacher(String name) 
        this.name = name;
        this.homeworks = new ArrayList<String>();
        this.homeworkListenerList = new HashSet<HomeworkListener>();
    

    public void setHomework(String homework) 
        System.out.printf("%s布置了作业%s\\n", this.name, homework);
        homeworks.add(homework);
        
        HomeworkEventObject event = new HomeworkEventObject(this);
        /*
         * 在观察者模式中,我们直接调用Observable的notifyObservers来通知被观察者
         * 现在我们只能自己通知了~~
         */
        for (HomeworkListener listener : homeworkListenerList) 
            listener.update(event, homework);
        
    

    public void addObserver(HomeworkListener homeworkListener) 
        homeworkListenerList.add(homeworkListener);
    


测试:

public class Client 

    public static void main(String[] args) 
        Student student1 = new Student("张三");
        Student student2 = new Student("李四");

        Teacher teacher1 = new Teacher("杨振宁");
        teacher1.addObserver(student1);
        teacher1.addObserver(student2);
        teacher1.setHomework("事件机制第二天作业");
    


执行main打印:

杨振宁布置了作业事件机制第二天作业
学生张三观察到(实际是被通知)杨振宁布置了作业《事件机制第二天作业》 
学生李四观察到(实际是被通知)杨振宁布置了作业《事件机制第二天作业》 

以上是关于java事件机制(订阅/消费模型)/观察者模式 : EventObject,EventListener和Source的主要内容,如果未能解决你的问题,请参考以下文章

Google Guava EventBus(事件总线)

消息机制

设计模式之观察者

模式发布与订阅模式和观察者模

Guava学习笔记:EventBus(转)

事件总线模式