观察者模式是什么?
观察者模式是对象中的一种一对多的依赖关系,当对应的状态发生改变时,执行相应的更新。
观察者模式有两个概念,分别是:
- 目标(发布者),
发布者它会记录所有的订阅者,当状态发生改变时,由发布者通知订阅者 - 观察者(订阅者) 所有的订阅者都有一个
update方法,这个方法是用于处理状态发生改变时的业务。
Vue响应机制中使用了观察者模式,在vue响应机制中,当数据变化的时候会调用观察者的update方法,update方法内部就是更新视图
在观察者模式中,订阅者的update方法是由发布者调用的。
实现一个简单的观察者模式
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>观察者模式</title></head><body><script>// 目标-发布者class Dep {constructor() {this.subs = [];}// 添加观察者addSub(sub) {if (sub && sub.update) {this.subs.push(sub)}}// 通知观察者notify() {this.subs.forEach(sub => {sub.update()})}}// 观察者-订阅class Watcher {update() {console.log("update")}}let dep = new Dep()let watcher = new Watcher()dep.addSub(watcher)dep.notify()</script></body></html>
发布订阅模式是什么?
发布订阅模式是对象中的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖与它的对象都将得到状态改变的通知。
发布定于模式有三个概念,分别是:
- 订阅者,订阅者的作用是:向调度中心注册一个事件,这个事件的作用是处理状态改变后的业务。
- 发布者,发布者的作用是:向调度中心发起一个状态改变的通知。
- 调度中心,调度中心的作用是:将发布者状态改变时向调度中心发送的通知,告知给订阅者。
看似很陌生,其实在工作中经常会用到。例如:
- node.js 中 EventEmitter 中的
on和emit - vue.js 中的
$on和$emit
他们都使用了发布订阅模式
例子
我们就拿微信公众号来举例子,我们很喜欢一个公众号的文章,但是我们不知道这个公众号什么时候发布文章,要不定时的去翻一翻。这个时候我们可以订阅这个公众号,每当这个公众号发布了新的文章的时候,我们就会收到通知。
这个例子中的发布者就是当前这个**公众号**,我们就是**订阅者**,微信就是**调度中心**
实现一个简单的发布订阅模式
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>发布订阅模式</title></head><body></body></html><script>class EventEmitter {constructor() {//设置对象的原型// { 'click': [fn1, fn2], 'change': [fn] }this.subs = Object.create(null)}// 注册事件$on(eventType, handler) {this.subs[eventType] = this.subs[eventType] || []this.subs[eventType].push(handler)}// 触发事件$emit(eventType) {if (this.subs[eventType]) {this.subs[eventType].forEach(handler => {handler();})}}}</script><script>// 调度中心let dispatch = new EventEmitter()// 注册事件(订阅消息) ,当调度中心有新的信息过来的时候,会触发相对应的函数dispatch.$on('dataChange', () => {console.log('dataChange')})dispatch.$on('dataChange', () => {console.log('dataChange1')})// 触发事件(发布消息),向调度中心发布信息dispatch.$emit('dataChange')</script>
发布者模式和观察者模式的区别
相同点:
都是对象中的一种一对多的依赖关系,当对应的状态发生改变时,执行相应的更新。
不同点:
1、发布者模式有调度中心,观察者模式没有调度中心。
2、发布者模式的更新是由调度中心发起的,而观察者模式的更新是由目标(订阅者)发起的
3、发布者模式,双方并不知道对方的存在,而观察者模式是必须要知道的,基础自定义事件。
4、发布者模式是低耦合的,而观察者是高耦合的。
使用场景:
观察者模式:vue依赖追踪、原生事件
发布订阅模式:vue的组件之间的通信EeventBus,react合成事件
下面的文章讲的很清楚,可以具体看看:
