观察者模式和发布订阅模式的区别

之前一直对观察者模式和发布订阅模式的区别理解不深,正好这段时间在看vue源码的分析,vue数据双向绑定也用到了发布订阅模式,于是又把这两者探究了一番,今天做个笔记加强印象。
观察者模式和发布订阅模式最大的区别就是发布订阅模式有个事件调度中心。

在这里插入图片描述

从图中可以看出,观察者模式中观察者和目标直接进行交互,而发布订阅模式中统一由调度中心进行处理,订阅者和发布者互不干扰。这样一方面实现了解耦,还有就是可以实现更细粒度的一些控制。比如发布者发布了很多消息,但是不想所有的订阅者都接收到,就可以在调度中心做一些处理,类似于权限控制之类的。还可以做一些节流操作。

接下来看一下代码实现
观察者模式:

// 观察者
class Observer {
    constructor() {

    }
    update(val) {

    }
}
// 观察者列表
class ObserverList {
    constructor() {
        this.observerList = []
    }
    add(observer) {
        return this.observerList.push(observer);
    }
    remove(observer) {
        this.observerList = this.observerList.filter(ob => ob !== observer);
    }
    count() {
        return this.observerList.length;
    }
    get(index) {
        return this.observerList[index];
    }
}
// 目标
class Subject {
    constructor() {
        this.observers = new ObserverList();
    }
    addObserver(observer) {
        this.observers.add(observer);
    }
    removeObserver(observer) {
        this.observers.remove(observer);
    }
    notify(...args) {
        let obCount = this.observers.count();
        for (let index = 0; index < obCount; index++) {
            this.observers.get(i).update(...args);
        }
    }
}

发布订阅模式:

class PubSub{
            constructor() {
                this.subscribers = {}
            }

            subscribe(type, fn) {
                if(!this.subscribers.hasOwnProperty(type)){
                    this.subscribers[type] = [];
                }
                if(this.subscribers[type].indexOf(fn) == -1) this.subscribers[type].push(fn);
            }

            unsubscribe(type, fn) {
                let listeners = this.subscribers[type];
                if (!listeners || !listeners.length) return;
                if(this.subscribers[type].indexOf(fn) != -1){
                    this.subscribers[type].splice(this.subscribers[type].indexOf(fn),1);
                }
            }

            publish(type, ...args) {
                let listeners = this.subscribers[type];
                if (!listeners || !listeners.length) return;
                listeners.forEach(fn => fn(...args));
            }

        }
        let ob = new PubSub();
        ob.subscribe('add', a);
        ob.subscribe('add', a);
        ob.subscribe('add', b);
        // ob.unsubscribe('add',a);
        ob.publish('add', 1,2,3);

从上面代码可以看出,观察者模式由具体目标调度,每个被订阅的目标里面都需要有对观察者的处理,会造成代码的冗余。而发布订阅模式则统一由调度中心处理,消除了发布者和订阅者之间的依赖。

观察者模式跟我们平时用的事件也有一定的关系,比如:

ele.addEventListener('click', () => {});

addEventListener就相当于注册了一个观察者,当观察到‘click’事件的时候,作出一些处理。

好啦,内容基本就这些,如果有什么不对的地方,欢迎指正哦~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值