发布-订阅模式、观察者模式的理解

67 阅读2分钟

发布——订阅模式

发布者 <——> 消息代理(即下例中的event_bus) <——> 订阅者

发布者向消息代理发送不同类型的消息,订阅者则从消息代理选择想要订阅的消息类型(发布和订阅不互相依赖,通过中间的消息代理通信)

class EventBus(){
    constructor()(
        //events的键是所有发布的事件,值是对应事件的订阅者们(的订阅回调行为)
        this.events = {}
    )

    //订阅(对某一事件订阅)
     subscribe(event_name, subscribe_cb){
        if(!this.events[event_name]) this.events[event_name] = []
        this.events[event_name].push(subscribe_cb)
    }
    
    //发布(某一事件发布相关args,该事件的订阅者们使用该args完成自己的回调行为)
    publish(event_name, ...args){
        if(!this.events[event_name]) return
        else{
            this.events[event_name].forEach(cb => {
                //此处具体情况具体分析
                cb(...args)
            })
        }
    }
    
    //取消订阅
    unsubscribe(event_name, subscribe_cb){
        if(!this.events[event_name]) return
        const subscribe_cbs = events[event_name]
        const idx = subscribe_cbs.indexOf(subscribe_cb)
        if(idx !== -1) subscribe_cbs.splice(idx, 1)
    }
    
    //撤回发布
    unpublish(event_name){
        delete this.events[event_name]
    }
}

let event_bus = new EventBus()

观察者模式

发布者知道所有订阅者,会自动进行消息推送。被观察者和观察者是一对多的依赖关系

class Observer(){
    constrctor(name){
        this.name = name
    }
    
    update(subject){
        console.log(`${this.name},当前你观察的对象的状态是${subject.get_state()}`);
        //进行系列操作
    }
}

class Subject(){
    constructor(){
        this.state = {}
        this.observers = []
    }
    
    add(observer){
        this.observers.push(observer)
    }
    
    remove(observer){
        const idx = this.observers.indexOf(observer)
        if(idx !== -1) this.observers.splice(idx, 1)
    }
    
    notify(){
        this.observers.forEach(observer => observer.update(this))
    }
    
    get_state(){
        return this.state
    }
    
    set_state(new_state){
        this.state = new_state
        this.notify()
    }
}

//两个舔狗时刻观察着女神的朋友圈
let tiangou1 = new Observer('舔狗1号')
let tiangou2 = new Observer('舔狗2号')
let nvshen = new Subject()
nvshen.add(tiangou1)
nvshen.add(tiangou2)

//女神发朋圈说今天好难过,这时舔狗1、2号均会接受到此消息
nvshen.set_state({'mood':'sad'})

观察者模式更标准的做法是:把Observer类作为父类供观察者们继承——子类可以重写update方法进行个性化操作;同时可以把Subject类作为抽象接口——把obervers属性、add、remove、notify三个方法抽离出来,而具体被观察类保存有自己的内部状态,比如:

class TianGou1 extends Observer{
    update(subject){
        //给女神买蜜雪冰城
    }
}

class TianGou2 extends Observer{
    update(subject){
        //给女神买茶颜悦色
    }
}

class NvShen extends Subject(){
    //女神独有的状态和方法
}

总结

两种模式的不同可以这样理解:观察者模式——你订了报社的报纸,每当有新报纸报社就会自己给你送来; 发布-订阅模式——公告栏上会更新信息,你需要自己去看