设计模式之观察者模式

1. 定义

当一个对象被修改时,则会自动通知依赖它的对象

2. 口语化表述

观察者模式或许听起来不是很耳熟,但是说起订阅模式,大部分人就能理解

比如,微信公众号里,你订阅的公众号如果发了新消息,微信就会通知你,你在你的微信里就能看到(没订阅自然不会收到)

其实这就是观察者模式(事件订阅者模式),多个对象观察(监听)某一对象,当这个对象发生变化时,观察的对象就会知道并作出变化

下面的描述会沿用这个上述这个场景

3. 源码示例

观察者模式在前端可是处处都能看到,比如浏览器事件机制

HTML页面里的元素很多都有内置的事件,比如Button具有监听点击事件

假设设置了点击事件的触发函数(onClick),当你点击了Button时,Button就会接收到这个事件并执行之前设置的触发函数(onClick)

这里看上去,是一对一的关系,就是一个点击事件触发一次函数,有没有一对多的呢?答案是有,比如,全局事件总线

全局事件总线,就是让事件系统置于全局,在系统的任意地方都能触发事件,在系统任意地方都能接收事件消息并执行对应函数

原理很简单,一个全局对象,实现发布事件的接口,实现订阅事件的接口,实现存储事件及对应触发函数,就是一个全局事件总线

Vue2 就实现了类似的接口,所以可以当作一个全局事件总线使用(Vue3 做了修改,无法再把Vue当作一个事件总线来使用)

Vue2 中的 Vue 原型对象上包含事件处理的方法:

  • $on(eventName, listener): 绑定自定义事件监听
  • $emit(eventName, data): 分发自定义事件
  • $off(eventName): 解绑自定义事件监听
  • $once(eventName, listener): 绑定事件监听, 但只能处理一次

所以,只要设置一个全局Vue对象,然后就可以在任意组件里绑定事件监听并设置更新函数,在任意组件里分发(触发)这个事件,这就实现了全局事件总线

全局事件总线就是观察者模式的典型应用,即一处修改,则会自动通知监听这处的其他地方并执行对应的函数

4. 总结

4.1 设计优点

  • 开闭原则

    在上述微信公众号示例中,新的用户加入与新的公众号加入,都无需修改现有的系统

4.2 适用场景

  • 一个对象状态的改变需要改变其他对象

    某个微信公众号修改了,需要自动通知订阅它的用户

  • 一些对象必须观察其他对象时

    浏览器事件机制里,必须触发对应的事件才能执行对应的函数

5. 参考资料

[1] 观察者设计模式 (refactoringguru.cn)

[2] 【Vue全局事件总线详解】 - 掘金 (juejin.cn)

posted @ 2024-01-17 23:32  当时明月在曾照彩云归  阅读(5)  评论(0编辑  收藏  举报