观察者模式
2020-11-02 本文已影响0人
小宇cool
1. 观察者模式
1.1 定义
观察者模式(Observer): 又称发布订阅模式, 定义了一对多的关系, 让多个观察者对象同时监听某一个对象
当该对象发生变化时, 多个观察者对象也能做出对应相应的改变.
就比如你用手机定了一个早上8点的闹钟,此时你相当于订阅者, 手机相当于发布者,发布者此时会观察时间的变化当时间到了8点,手机就会发布消息, 提醒订阅者赶紧起床
1.2 作用
- 建立一套触发机制, 当一个对象的状态发生改变时, 所有依赖它的对象都会得到通知并自动更新.
- 将观察者和被被观察者进行解耦, 使它们都各自能独立变化,不会影响到另一边的变化.
1.3 应用场景
- 场景一
事件绑定机制, 其实就是一个观察者模式, 事件触发的时候(发布消息)就执行对应的事件函数(订阅者)
let box = document.querySelector('.box');
function action(){
console.log('事件被触发了')
}
box.addEventListener('click', action)
上面是一个非常简单事件绑定代码, 我们通过addEventListener给box元素绑定了一个点击事件以及对应的事件函数, 此时addEventListener相当于观察者, 对应的事件函数为订阅者, 当事件触发时, 观察者则就会发布消息,执行相应的事件函数.
- 场景二
观察者模式的基本模式, 从简单的功能到复杂的实现
class Observer{
constructor(){
this.subscribes = []
}
// 订阅
on(fn){
this.subscribes.push(fn)
}
//发布
emit(msg){
this.subscribes.forEach((v) => v(msg))
}
}
let observer = new Observer()// 定义基础观察者对象
observer.on((msg) =>{
console.log(111+msg);
})
observer.on(() => {
console.log(222+"msg");
})
observer.trigger('dd')
上面的代码我们通过定义了一个Observer类, 并为其实例对象定义一个subscribes属性用来保存所有的订阅者, 通过on方法添加响应的订阅者, 然后通过emit方法来发布消息,并执行对应的订阅者的事件函数.
进阶版观察者
// 进阶版观察者
class Observer {
constructor() {
//储存订阅者
this.subscribes = {}
}
//订阅
on(name, callback) {
// 如果不存在这个订阅者就添加这个订阅者
if (!this.subscribes[name]) {
this.subscribes[name] = [];
}
this.subscribes[name].push(callback)
}
// 发布
emit(name, msg) {
// 如果不存在这个订阅者就打断函数执行
if (!this.subscribes[name]) throw new Error('未找到订阅者');;
this.subscribes[name].forEach(fn => fn(msg))
}
//解绑
off(name, callback) {
let callbackList = this.subscribes[name];
if (!callbackList) throw new Error('未找到订阅者');
// 找出对应订阅者的事件函数并从删除
let index = callbackList.indexOf(callback);
if (index === 1) return
else callbackList.splice(index, 1)
}
}
let observer = new Observer();
console.log(observer)
function update1(msg){
console.log(11,msg);
}
function update2(msg){
console.log(22,msg);
}
function update3(msg) {
console.log(33,msg);
}
observer.on('touch',update1)
observer.on('touch', update2)
observer.on('touch', update3)
observer.on('log', function(){
console.log('log')
})
observer.off('touch', update1)
observer.emit('touch',"dd")
observer.emit('age')
我们可以在控制台打印出如下结果
image-20201102205150749.png总结: 当一个对象的改变将导致多个对象导致改变时,而不知道具体有多少对象将发生改变, 使用观察者模式就非常合适, 可以降低对象之间的耦合度.