观察者模式与发布订阅模式

1、观察者模式

1.1、定义

观察者模式,即观察者监听被观察者的变化,被观察者发生改变时,通知所有的观察者。

其实,观察者模式就类似于事件的监听addEventListener,比如:

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

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

1.2、代码实现
// 举例:消费者订阅商店的商品推送信息

// 被观察者
class Subject {
    constructor() {
        this.observer = []  // 已订阅的观察者对象
    }
    // 顾客订阅商店的商品事件
    subscribe(observer) {
        this.observer.push(observer)
    }
    // 通知顾客
    notify(msg) {
        this.observer.forEach(ob => {
            ob.getMessage(msg)
        })
    }
    // 取消订阅
    unsubscribe(observer){
        this.observer = this.observer.filter(ob => ob !== observer);
    }
    
}
 
// 观察者
class Observer {
    constructor(name) {
        this.name = name;
        
    }
    // 接受商店派发的消息
    getMessage(goodsCount) {
        console.log(`${this.name}收到消息了, ${goodsCount}`)
    }
}
 
let subject = new Subject()
let o1 = new Observer('张三')
let o2 = new Observer('李四')
subject.subscribe(o1)
subject.subscribe(o2)
 
subject.notify('全场打8折了!')  // 修改商品的数量,订阅者将收到消息

subject.unsubscribe(o1);    // o1取消订阅
subject.notify('清空大甩卖了!')  // 修改商品的数量,订阅者将收到消息

2、发布订阅模式

class EventEmitter {
    constructor(maxListeners){
        this.events = {};
        // maxListeners  同一事件,监听的最大回调函数个数
        this.maxListeners = maxListeners || Infinity;

    }

    emit(event,...args){
        const cbs = this.events[event];

        if(!cbs){
            console.warn(`${event} event is not register!`)
            return this;
        }

        cbs.forEach( cb => cb.apply(this,args));
        return this;
    }

    on(event,cb){
        if(!this.events[event]){
            this.events[event] = []
        }
        if(this.maxListeners !== Infinity && this.events[event].length >= this.maxListeners){
            console.warn(`${event} event has reached max listeners!`);
            return;
        }

        this.events[event].push(cb);
        return this;

    }

    once(event,cb){
        const func = (...args)=>{
            this.off(event,func);
            cb.apply(this,args);
        }

        this.on(event,func);
        return this;

    }

    off(event,cb){
        if(!cb){
            this.events[event] = null;
        }else{
            this.events[event] = this.events[event].filter(item=> item !== cb );
        }
        return this;

    }
}

const add = (a,b) => console.log(a + b);
const log = (...args) => console.log(...args);
const event = new EventEmitter()

event.on('add',add);
event.on('log',log);
event.emit('add',1,2);    // 3
event.emit('log','hi~');  // 'hi~'
event.off('add');
event.emit('add',1,2);   // Error: add event is not register

event.once('once',add)
event.emit('once',1,2);   // 3
event.emit('once',1,2);   // Error: once event is not register
event.emit('once',1,2);  

3、观察者模式与发布订阅模式的区别

观察者模式和发布订阅模式最大的区别就是发布订阅模式有个事件调度中心
在这里插入图片描述

3.1、具体区别如下
  • 是否直接进行交互
    观察者模式中观察者和目标直接进行交互
    发布订阅模式中统一由调度中心进行处理,订阅者和发布者互不干扰

  • 耦合程度 ----- 这是由于是否直接进行交互所引起的
    观察者模式中,由于它们之间是直接进行交互,所以组件之间强耦合
    发布订阅模式中,由于它们之间是通过调度中心进行处理,所以组件之间松耦合。由于调度中心的存在,使得可以进行更细粒度的一些控制。比如发布者发布了很多消息,但是不想所有的消息订阅者都会接收到,这就可以在调度中心做一些处理,类似于权限控制之类的。还可以做一些节流操作。

作者:snow_in
链接:https://www.jianshu.com/p/594f018b68e7
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值