个人理解的观察者模式和发布订阅模式

96 阅读1分钟

观察者模式

观察者模式,属于行为型模式的一种,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态变化时,会通知所有的观察者对象,使他们能够自动更新自己。我的理解就是父亲母亲直接观察宝宝,没有依赖中间件。 `

class Subject{

    constructor(name){
        this.name=name
        this.state='开心'
        this.observer=[]

    }

    attach(who){
        this.observer.push(who)
    }

    setState(state){
        this.state=state
        this.observer.forEach((item)=>{
            item.updated(this)
        })

    }

}

class Observer{
    constructor(name){
        this.name=name
    }

    updated(subject){
        console.log(`我是${this.name},我观察的${subject.name}状态是${subject.state}`)           
    }
}



let baby=new Subject('babyhan')
let father=new Observer('fatherhan')
let mother=new Observer('motherhan')
baby.attach(father)
baby.attach(mother)
baby.setState("超级开心")
</script>

`

发布订阅模式

从我的理解角度出发,当我们在浏览b站时,遇到感兴趣的up主,我们通常会选择关注他。这样一来,每当他们发布一个新的内容,网站通过消息通知我们。而转换为理解,就是我们关注这个up主,并且订阅了他给我们发消息的,up主负责发布他要发布的视频,up主自始至终并不知道粉丝的存在,不知道谁订阅了他。而这就是一个典型的订阅发布模式。他有三个主体,任务发布者(subscriber)对象,事件调度站(emit,on,remove),还有一个任务的接受者。在实际应用比如addeventListener,eventBus。 `

    class PublishSub{
        subscribes=new Map()

        getuid(){
            return Math.random()+Date.now()
            
        }

        // 订阅
        on(subscribe,callback){
            const subscribeCallbak=this.subscribes.get(subscribe)||new Map()
            const uuid=this.getuid()
            this.subscribes.set(subscribe,subscribeCallbak);
            subscribeCallbak.set(uuid,callback)
            return uuid

        }


        // 发布
        emit(subscribe,...arg){
            const subscribeCallbak=this.subscribes.get(subscribe)||new Map()

            for(const [uuid,callback] of subscribeCallbak){
                callback.call(this,...arg)
            }


        }


        // 取消订阅
        remove(value){
            const isSubscribe=this.subscribes.get(value)
            if(isSubscribe){
                this.subscribes.delete(value)
                console.log(value,"事件名取消成功")
            }
            else{
                for(const [subscribe,subscribeCallback] of this.subscribes){
                    for(const [uuid,callback] of subscribeCallback){
                        subscribeCallback.delete(value)
                        console.log(`uuid${value}取消成功`)
                    }
                }
            }
        }
    }

    const pubsub=new PublishSub()
    pubsub.on('A',(a)=>{
        console.log("订阅时间a",a)
    })

    pubsub.on('B',(b)=>{
        console.log("订阅时间a",b)
    })

    pubsub.emit('A',2000000)
    pubsub.emit('B',2000)

    setTimeout(()=>{
        pubsub.remove('B')
    })`

总结

观察者模式与发布订阅模式最大的区别就是,观察者模式是观察者直接观察目标对象,没有中介层。而发布订阅模式多了一个中介层,发布者和订阅者依赖于中介层,并不直接通信。

image.png