javascript观察者模式
观察者模式又称发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、源-监听器(Source/Listener)模式或从属者(Dependents)模式。
观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听一个主题对象。这个主题对象在状态上发生变化时,会通知所有观察者,使它们能够自动更新自己。
下面拿老外的例子改一改,练练手。
var dom = { each : function (obj,fn,score){ for ( var key in obj){ if (obj.hasOwnProperty(key)) fn.call(score,obj[key],key,obj) } } }; dom.each({ indexOf: function (el, index) { var n = this .length, i = index == null ? 0 : index < 0 ? Math.max(0, n + index) : index; for (; i < n; i++) if (i in this && this [i] === el) return i; return -1; }, //移除 Array 对象中指定位置的元素。 removeAt: function (index) { return this .splice(index, 1) }, //移除 Array 对象中某个元素的第一个匹配项。 remove: function (item) { var index = this .indexOf(item); if (index !== -1) this .removeAt(index); return item; } }, function (method,name){ if (!Array.prototype[name]) Array.prototype[name] = method; }); /* 订阅者接口 */ var Observer = function () { //观察者要实现的方法 this .update = function () { throw "此方法必须被实现!" } } /* 发布者接口 */ var Subject = function () { this .observers = []; } Subject.prototype = { //如果状态发生改变,通知所有观察者调用其update方法 notifyObservers : function (context) { for ( var i = 0, n = this .observers.length; i < n; i++) { this .observers[i].update(context); } }, // 添加订阅者 attach : function (observer){ if (!observer.update) throw 'Wrong observer' ; this .observers.push(observer); }, /* 移除订阅者 */ detach : function (observer) { if (!observer.update) { throw 'Wrong observer' ; } this .observers.remove(observer); } } //实现接口 var implement = function (Concrete,Interface){ for ( var prop in Interface) { Concrete[prop] = Interface[prop]; } } /***************** 发布者的实现类 ***********************/ var mainCheck = document.createElement( "input" ); mainCheck.type = 'checkbox' ; mainCheck.id = 'MainCheck' ; mainCheck.style.cssText = 'border:1px solid red' ; implement( mainCheck, new Subject()); /* 当点击按钮的时候 给相关的观察者发送通知. 观察者接收到通知的时候 改变状态 */ mainCheck[ 'onclick' ] = function (){ this .notifyObservers( this .checked) } document.body.appendChild(mainCheck); /********************* 订阅者的实现类 *****************************/ var obsCheck1 = document.createElement( 'input' ); var obsCheck2 = document.createElement( 'input' ); obsCheck1.type = 'checkbox' ; obsCheck1.id = 'Obs1' ; document.body.appendChild(obsCheck1); obsCheck2.type = 'checkbox' ; obsCheck2.id = 'Obs2' ; document.body.appendChild(obsCheck2); implement( obsCheck1, new Observer()); implement( obsCheck2, new Observer()); /* 必须实现它们的具体update方法 */ obsCheck1.update = function (value) { this .checked = value; } obsCheck2.update = function (value) { this .checked = value; } // 将发布者和订阅者(观察者)关联 mainCheck.attach(obsCheck1); mainCheck.attach(obsCheck2); |
这东西比较简单,涉及两个阵营。一个是发布者,你把它当成服务器端就是,肯定要做比客户端更多的事。为此,发布者要拥有订阅者的列表,支持添加或删除它们,当自己更新时,同步更新订阅者相应的东西。订阅者则不需要做许多事,只要提供一个update方法,供发布者调用就是。写这个时,我总是想起RSS,我的博客更新,便立即更新订阅者google reader上的内容。不过,javascript拥有DOM过门的事件系统,除非涉及的几个对象都不是元素节点,一般很少自己重新造轮子。
注:本文为rightjs学习笔记的一部分。
如果您觉得此文有帮助,可以打赏点钱给我支付宝1669866773@qq.com ,或扫描二维码


机器瞎学/数据掩埋/模式混淆/人工智障/深度遗忘/神经掉线/计算机幻觉/专注单身二十五年
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器