大话设计模式——观察者模式和发布/订阅模式的区别

观察者模式和发布/订阅模式,有相当多的程序员,尤其是前端,完全分不清他们之间的区别,甚至认为这两个设计模式是同一个。

其实这两个设计模式用一句话就可以区分其差别:观察者模式观察的是被观察者本身,而发布订阅模式订阅的是主题

从API设计到数据流转

观察者模式

观察者模式通常有两个核心api:

  • observable: 将数据包装为可观察对象
  • observer:观察可观察者
javascript 复制代码
const obj$ = observable({name:'a'})
observer(obj$,(snapshot?)=>{console.log('change')})
obj$.name = 'b';// change

一般情况下,observer只需要知道该对象发生变化 即可,如果需要知道变化内容,也仅提供快照或部分快照

发布订阅模式

发布订阅模式通常有三个api:

  • dispath(或emit)
  • subscribe(或on)
  • unsubscribe(或off)
javascript 复制代码
const unsubscribe = messageCenter.subscribe('weather',(info)=>{console.log('天气',info)})
messageCenter.dispatch('weather','Sunny');// 天气: sunny
unsubscribe()//取消订阅

订阅的内容往往是一个主题,所以响应内容中必定带上该主题的内容。虽然一般都是订阅后再接收该主题内容,但也可以订阅后立即获取该主题历史内容,甚至设置推送频率、内容分组和过滤等。

概念陷阱

这里最容易产生理解偏差的地方就是发布订阅模式中的发布者和订阅者是谁?

上文代码中,表面上看,messageCenter自己订阅,自己发布,又是订阅者,又是发布者。但实际上,我们应该将调用订阅方法的地方看成是订阅者,将调用发布方法的地方,看成发布者。比如class A的某个方法中进行了订阅,则该class A的实例就是订阅者,class B的某个方法中调用了发布,则class B的实例,就是发布者。从这个角度看,发布者与订阅者是解耦的,两者互不关心对方的存在,都和messageCenter单向联系,因此,这里的messageCenter往往也叫做事件总线(EventBus),相当于用事件/消息这根线串起多个互不关联对象。

而观察者模式,观察者对被观察者有直接依赖,对被观察者的响应或通知,并不需要进行主题区分和内容响应,因为被观察者本身就是观察的内容,并且观察者本身就拥有或能直接获取到被观察者对象

相关推荐
胡斌附体10 小时前
使用Electron创建helloworld程序
前端·javascript·electron·nodejs·pc
toobeloong10 小时前
Electron 从低版本升级到高版本 - webview通信的改造
前端·javascript·electron
im_AMBER11 小时前
React 01
前端·javascript·笔记·react.js·前端框架·web
@大迁世界11 小时前
React 19.2.0 有哪些新变化
前端·javascript·react.js·前端框架·ecmascript
程序猿DD11 小时前
Java 25 中的 6 个新特性解读
java·后端
稻草猫.11 小时前
文件 IO
java·笔记·后端·java-ee·idea
掘金码甲哥11 小时前
有关CORS跨域访问,这事没完
后端
码事漫谈12 小时前
从外行到AI指挥官:你必须掌握的五大「程序员思维」
后端
华仔啊12 小时前
用 Vue3 + Canvas 做了个超实用的水印工具,同事都在抢着用
前端·vue.js·canvas