设计模式20:观察者模式(Observer)

1. 简介

- 观察者模式,又被成为发布订阅模式,
- 当一个对象的状态发生改变之后,会主动通知所有观察者,
- 然后每个观察者执行自己相应的函数
1.1 优点
- 被观察的对象和观察者之间解耦,方便扩展
- 观察者之间相互解耦,只是实现了共同接口
1.2 缺点
- 在单线程环境中,观察者收到通知的时间会比较长
1.3 使用场景
- 事件驱动模式:
    按钮点击,页面刷新等等
- 广播模式:
    系统启动时,通知各个组件

2.实现代码

这里使用了观察者模式的一个扩展模式,
也就是事件监听器模式来实现
2.1 具体逻辑
领导和老板都希望员工能好好工作,
就找人监听员工yanggx的工作状态,
当yanggx工作状态改变的时候,
监听者就会将事件汇报领导和老板,
这里就涉及到四个组成部分:事件源,事件,监听器和事件发布器
2.1.1事件源
yanggx这个人,对应的类是Yanggx
/**
 * 事件源,也就是被监听的对象,
 * 这里是yanggx这个人
 */
public class Yanggx {
    private String state;
    public String getState() {
        return state;
    }
    public void setState(String state) {
        this.state = state;
    }
}
2.1.2事件
- yanggx所发生的事件,对应抽象类YanggxEvent
- 我们主要监听工作事件,所以只有一个实现类YanggxWorkEvent
/**
 * yanggx事件
 */
public abstract class YanggxEvent extends EventObject {
    private static final long serialVersionUID = -1336288592330402915L;
    public YanggxEvent(Object source) {
        super(source);
    }
}
/**
 * 工作事件
 */
public class YanggxWorkEvent extends YanggxEvent {

    private static final long serialVersionUID = -4366933029591990461L;

    public YanggxWorkEvent(Yanggx yanggx) {
        super(yanggx);
    }
}
2.1.3 监听器
- 就是对yanggx工作感兴趣的人,对应接口YanggxListener
- 对yanggx工作感兴趣的有大Boss,对应实现类YanggxBossListener,
- 还有上级领导也感兴趣,对应实现类YanggxLeaderListener
/**
 * yanggx事件的监听器
 */
public interface YanggxListener<E extends YanggxEvent> extends EventListener {
    /**
     * 监听到事件之后,触发的动作
     * @param event
     */
    void onYanggxEvent(E event);
}

/**
 * yanggx的老板监听器
 */
public class YanggxBossListener implements YanggxListener<YanggxEvent> {

    @Override
    public void onYanggxEvent(YanggxEvent event) {
        Yanggx yanggx = (Yanggx) event.getSource();
        System.out.println("Boss:我不认识他,所以不做任何处理");
    }
}

/**
 * yanggx的领导监听器
 */
public class YanggxLeaderListener implements YanggxListener<YanggxEvent> {

    @Override
    public void onYanggxEvent(YanggxEvent event) {
        Yanggx yanggx = (Yanggx) event.getSource();
        System.out.print("Leader:上班时间" + yanggx.getState() + "赶紧起来干活");
    }
}
2.1.4事件发布器
就是将工作事件汇报给上级领导的人,对应的类是YanggxEventPublisher
/**
 * 事件发布器
 */
public class YanggxEventPublisher {

    List<YanggxListener<YanggxEvent>> listeners = new ArrayList<>();

    /**
     * 注册监听器
     * 
     * @param listener
     */
    public void registListener(YanggxListener<YanggxEvent> listener) {
        listeners.add(listener);
    }

    /**
     * 发布事件
     * 
     * @param event
     */
    public void publishEvent(YanggxEvent event) {
        System.out.println("发布Yanggx事件开始...");
        for (YanggxListener<YanggxEvent> listener : listeners) {
            listener.onYanggxEvent(event);
        }
    }
}
2.2 类图
观察者模式
2.3 代码测试
//测试类
public class ObserverTest {
    public static void main(String[] args) {
        // 事件源:yanggx
        Yanggx yanggx = new Yanggx();
        yanggx.setState("睡觉...");
        // 事件
        YanggxEvent event = new YanggxWorkEvent(yanggx);
        // 在事件发布者中注册监听器
        YanggxEventPublisher publisher = new YanggxEventPublisher();
        publisher.registListener(new YanggxBossListener());
        publisher.registListener(new YanggxLeaderListener());
        // 发布事件
        publisher.publishEvent(event);
    }
}

运行结果:
    发布Yanggx事件开始...
    Boss:我不认识他,所以不做任何处理
    Leader:上班时间睡觉...赶紧起来干活
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 13,902评论 1 32
  •   JavaScript 与 HTML 之间的交互是通过事件实现的。   事件,就是文档或浏览器窗口中发生的一些特...
    霜天晓阅读 8,912评论 1 11
  • 想起来一个小唐语录舒缓一下心情:假期某个周末在床上起腻,小唐说,媳妇今天怎么这么乖啊?我答:我一直像一只小猫咪一样...
    豫吉阅读 1,292评论 0 0
  • UITableView的简单认识 UITableView最核心的思想就是UITableViewCell的重用机制。...
    reallychao阅读 4,699评论 0 7
  • 时间:2017/03/19 10:00~12:00 地点:深圳市天安数码城安徽大厦27楼 人物:麦麦、万芳、杜姝、...
    我生君未生君生我已老阅读 3,434评论 0 0

友情链接更多精彩内容