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打印:

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值