当前位置: 首页 > 科技观察

面试官:说说你对发布订阅模式和观察者模式的理解?区别?

时间:2023-03-20 23:56:59 科技观察

文末,本文转载自微信公众号《JS每日一问》,作者灰灰。转载本文请联系JS每日一问公众号。1.观察者模式观察者模式定义了对象之间一对多的依赖关系。当一个对象的状态发生变化时,所有依赖它的对象都会得到通知并自动更新。观察者模式属于行为行为模型关注的是对象之间的通信,观察者模型是观察者与被观察者之间的通信。比如在生活中,我们可以通过订阅报纸来说明形象。当你订阅了一份报纸,每天都会给你送一份最新的报纸,有多少人订阅了报纸,报社就发多少份报纸,报社和订阅报纸的顾客就形成了一个-对多依赖。实现代码如下:Observed观察者模式classSubject{constructor(){this.observerList=[];}addObserver(observer){this.observerList.push(observer);}removeObserver(observer){constindex=this.observerList。findIndex(o=>o.name===observer.name);this.observerList.splice(index,1);}notifyObservers(message){constobservers=this.observeList;observers.forEach(observer=>observer.notified(消息));}}观察者:classObserver{constructor(name,subject){this.name=name;if(subject){subject.addObserver(this);}}notified(message){console.log(this.name,'收到消息',消息);}}使用代码如下:主题。删除观察者(观察者verA);subject.notifyObservers('Helloagain');上面代码中,观察者主动申请加入被观察者的列表,被观察者主动将观察者添加到列表中2.发布-订阅模式发布-订阅是一种消息范式。消息的发送者(称为发布者)不直接将消息发送给特定的接收者(称为订阅者)相反,它将发布的消息分为不同的类别,而不知道可能存在哪些订阅者(如果有)。同样,订阅者可以表达对一个或多个类别的兴趣,只接收感兴趣的消息,而不知道存在哪些发布者,实现代码如下:classPubSub{constructor(){this.messages={};this.listeners={};}//添加发布者publish(type,content){constexistContent=this.messages[type];if(!existContent){this.messages[type]=[];}this.messages[type].push(content);}//添加订阅者subscribe(type,cb){constexistListener=this.listeners[type];if(!existListener){this.listeners[type]=[];}this.listeners[type].push(cb);}//notifynotify(type){constmessages=this.messages[type];constsubscribers=this.listeners[type]||[];subscribers.forEach((cb,index)=>cb(messages[index]));}}发布者代码如下:classPublisher{constructor(name,context){this.name=name;this.context=context;}publish(type,content){this.context.publish(type,content);}}订阅者代码如下:classSubscriber{constructor(name,context){this.name=名称;this.context=context;}subscribe(type,cb){this.context.subscribe(type,cb);}}使用以下代码:constTYPE_A='music';constTYPE_B='movie';constTYPE_C='novel';constpubsub=newPubSub();constpublisherA=newPublisher('publisherA',pubsub);publisherA.publish(TYPE_A,'weareyoung');publisherA.publish(TYPE_B,'thesiliconvalley');constpublisherB=newPublisher('publisherB',pubsub);publisherB.publish(TYPE_A,'stronger');constpublisherC=newPublisher('publisherC',pubsub);publisherC.publish(TYPE_C,'abriefhistoryoftime');constsubscriberA=newSubscriber('subscriberA',pubsub);subscriberA.subscribe(TYPE_A,res=>{console.log('subscriberAreceived',res)});constsubscriberB=newSubscriber('subscriberB',pubsub);subscriberB.subscribe(TYPE_C,res=>{console.log('subscriberBreceived',res)});constsubscriberC=newSubscriber('subscriberC',pubsub);subscriberC.subscribe(TYPE_B,res=>{console.log('subscriberCreceived',res)});pubsub.notify(TYPE_A);pubsub.notify(TYPE_B);pubsub.notify(TYPE_C);上面代码中,需要通过发布订阅中心关联发布者和订阅者。发布者的发布动作和订阅者的订阅动作是相互独立的,不需要互相关注。发布订阅中心负责消息分发。都是一样的,举个生活中的例子:观察员模式:某公司给员工发月饼和粽子,是公司行政部门派发的。这件事不适合第三方,因为“公司”和“员工”;是一个整体的发布-订阅模型:一个公司想给别人发各种快递,因为“公司”和“别人”是独立的,它唯一的桥梁就是“快递”,所以这个事情适合第一个的时候三方快递公司解决上述过程,如果公司自行管理快递的派送,公司将成为业务复杂、难以管理的快递公司,影响公司自身的主营业务。因此,需要考虑使用哪种模式。两者需要耦合的区别如下图所示:在观察者模式下,观察者知道Subject,Subject一直记录着观察者。但是,在发布-订阅模式下,发布者和订阅者并不知道对方的存在。它们仅通过消息代理进行通信。在发布-订阅模式中,组件是松耦合的,与观察者模式正好相反。观察者模式主要是同步的。例如,当一个事件被触发时,Subject会调用观察者的方法。发布-订阅模型大多是异步的(使用消息队列)参考https://zh.wikipedia.org/zh-hans/%E8%A7%82%E5%AF%9F%E8%80%85%E6%A8%A1%E5%BC%8Fhttps://zh.wikipedia.org/wiki/%E5%8F%91%E5%B8%83/%E8%AE%A2%E9%98%85https://www.cnblogs.com/onepixel/p/10806891.htmlhttps://juejin.cn/post/6978728619782701087