观察者模式

2020-11-02  本文已影响0人  小宇cool

1. 观察者模式

1.1 定义

观察者模式(Observer): 又称发布订阅模式, 定义了一对多的关系, 让多个观察者对象同时监听某一个对象

当该对象发生变化时, 多个观察者对象也能做出对应相应的改变.

就比如你用手机定了一个早上8点的闹钟,此时你相当于订阅者, 手机相当于发布者,发布者此时会观察时间的变化当时间到了8点,手机就会发布消息, 提醒订阅者赶紧起床

1.2 作用

  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

总结: 当一个对象的改变将导致多个对象导致改变时,而不知道具体有多少对象将发生改变, 使用观察者模式就非常合适, 可以降低对象之间的耦合度.

上一篇下一篇

猜你喜欢

热点阅读