摘要:最近被人问到设计模式,观察者模式和发布订阅模式二者有什么区别。观察者模式观察者模式,目标和观察者是基类,目标提供维护观察者的一系列方法,观察者提供更新接口。
最近被人问到设计模式,观察者(Observer)模式和发布(Publish)/订阅(Subscribe)模式二者有什么区别。其实这两种模式还是有些许差异的,本质上的区别是调度的方式不同。
观察者模式观察者模式,目标和观察者是基类,目标提供维护观察者的一系列方法,观察者提供更新接口。具体观察者和具体目标继承各自的基类,然后具体观察者把自己注册到具体目标里,在具体目标发生变化时候,调度观察者的更新方法。
比如有个“天气中心”的具体目标A,专门监听天气变化,而有个显示天气的界面的观察者B,B就把自己注册到A里,当A触发天气变化,就调度B的更新方法,并带上自己的上下文。
示例
// 观察者列表 function ObserverList () { this.observerList = []; } ObserverList.prototype.add = function (obj) { return this.observerList.push(obj); } ObserverList.prototype.count = function () { return this.observerList.length; } ObserverList.prototype.get = function (index) { if (index > -1 && index < this.observerList.length) { return this.observerList[index]; } } ObserverList.prototype.indexOf = function (obj, startIndex) { var i = startIndex || 0; while (i < this.observerList.length) { if (this.observerList[i] === obj) { return i; } i++; } return -1; } ObserverList.prototype.removeAt = function (index) { this.observerList.splice(index, 1); } // 目标 function Subject () { this.observers = new ObserverList(); } Subject.prototype.addObsever = function (observer) { this.observers.add(observer); } Subject.prototype.removeObsever = function (observer) { this.observers.removeAt(this.observers.indexOf(observer, 0)); } Subject.prototype.notify = function (context) { var observerCount = this.observers.count(); for(var i = 0; i < observerCount; i++) { this.observers.get(i).update(context); } } // 观察者 function Observer () { this.update = function (context) { console.log(context); } } var mySubject = new Subject(); mySubject.addObsever(new Observer); mySubject.notify("hello world");发布/订阅模式
发布/订阅模式,订阅者把自己想订阅的事件注册到调度中心,当该事件触发时候,发布者发布该事件到调度中心(顺带上下文),由调度中心统一调度订阅者注册到调度中心的处理代码。
比如有个界面是实时显示天气,它就订阅天气事件(注册到调度中心,包括处理程序),当天气变化时(定时获取数据),就作为发布者发布天气信息到调度中心,调度中心就调度订阅者的天气处理程序。
// 发布、订阅模式 var pubsub = {}; (function (myObject){ var topics = {}; var subUid = -1; // 发布指定订阅 myObject.publish = function (topic, args) { if (!topics[topic]) { return false; } var subscribers = topics[topic]; var len = subscribers ? subscribers.length : 0; while(len--) { subscribers[len].func(topic, args); } return this; } // 向订阅中心添加订阅 myObject.subscribe = function (topic, func) { if (!topics[topic]) { topics[topic] = []; } var token = (++subUid).toString(); topics[topic].push({ token: token, func: func }) return token; } // 向订阅中移除订阅 myObject.unSubscribe = function (token) { for (var m in topics) { if (topics[m]) { for (var i = 0, j = topics[m].length; i < j; i++) { if (topics[m][i].token === token) { topics[m].splice(i, 1); return token; } } } } return this; }; })(pubsub); pubsub.subscribe("test", ()=>{console.log("hello world")}); pubsub.publish("test");总结
虽然两种模式都存在订阅者和发布者(具体观察者可认为是订阅者、具体目标可认为是发布者),但是观察者模式是由具体目标调度的,而发布/订阅模式是统一由调度中心调的,所以观察者模式的订阅者与发布者之间是存在依赖的,而发布/订阅模式则不会。
两种模式都可以用于松散耦合,改进代码管理和潜在的复用
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/99131.html
摘要:发布者注册发布订阅者自动打印消息消息观察者模式与发布订阅模式类似。在此种模式中,一个目标物件在它本身的状态改变时主动发出通知,观察者收到通知从而使他们的状态自动发生变化。 做为非科班出身的前端er,每次听到设计模式都感觉很高大上,总感觉这些东西是造火箭原子弹用的,距离我们这些造螺丝钉很遥远。但是最近在做一个聊天消息的业务时,发现貌似用上发布订阅模式业务就很清晰了。创建一个消息类当作发布...
摘要:观察者模式定义设计模式中对的定义一个对象称为维持一系列依赖于它观察者的对象,将有关状态的任何变更自动通知给它们。如图模式比较观察者模式则多了一个类似于话题调度中心的流程,发布者和订阅者解耦。 Obeserver(观察者)模式 定义 《js设计模式》中对Observer的定义:一个对象(称为subject)维持一系列依赖于它(观察者)的对象,将有关状态的任何变更自动通知给它们。 《设计模...
摘要:概念观察者模式被广泛地应用于客户端编程中。所有的浏览器事件,等都是使用观察者模式的例子。在观察者模式中,一个对象订阅另一个对象的指定活动并得到通知,而不是调用另一个对象的方法。此外,观察者模式还可用于实现数据绑定。 概念 观察者模式被广泛地应用于JavaScript客户端编程中。所有的浏览器事件(mouseover,keypress等)都是使用观察者模式的例子。这种模式的另一个名字叫自...
摘要:期设计模式如何理解观察者发布订阅模式定义观察者模式又叫发布订阅模式,它定义了一种一对多的关系,让多个观察者对象同时监听某一个主题对象,这个主题对象的状态发生变化时就会通知所有的观察者对象,使得它们能够自动更新自己生活实例理解你今天去看一个 20190411期 设计模式-如何理解观察者(发布订阅)模式? 定义: 观察者模式又叫发布订阅模式(Publish/Subscribe),它定义了一...
阅读 2128·2023-04-25 20:45
阅读 1033·2021-09-22 15:13
阅读 3617·2021-09-04 16:48
阅读 2565·2019-08-30 15:53
阅读 908·2019-08-30 15:44
阅读 879·2019-08-30 15:43
阅读 972·2019-08-29 16:33
阅读 3416·2019-08-29 13:08