【读书笔记】读《JavaScript设计模式》之观察者模式

一、定义

  在事件驱动的环境中,比如浏览器这种持续寻求用户关注的环境中,观察者模式(又名发布者-订阅者(publisher-subscripber)模式)是一种管理人与其任务之间的关系(确切地讲,是对象及其行为和状态之间的关系)的得力工具.用JavaScript的话来说,这种模式的实质就是你可以对程序中某个对象的状态进行观察,并且在其发生改变时能够得到通知。

二、例子

  我们需要一个发布者的构造函数,它为该实例定义了一个类型为数组的属性,用来保存订阅者的引用。

function Publisher() {
this.subscribers = [];
}

  接下来,构建订阅方法。所有Publisher实例都应该能够投送数据。只要把deliver方法添加到Publisher的prototype中,它就能够被所有Publisher对象共享。


// 订阅者订阅能力
Function.prototype.subscribe = function(publisher) {
var that = this,
alreadyExists = false,
i,
len = publisher.length;

for(i = 0; i < len; i++) {
if (el === this) {
alreadyExists = true;
}
}

if (!alreadyExists) {
publisher.subscribers.push(this);
}

return this;
};

// 订阅者具有退订能力
Function.prototype.unSubscribe = function(publisher) {
var that = this,
array = [],
len = publisher.length;

for(i = 0; i < len; i++) {
if (el !== this) {
array.push(this);
}
}

publisher.subscribers = array;

return this;
};

  应用之——


// 订阅者订阅能力
Function.prototype.subscribe = function(publisher) {
var that = this,
alreadyExists = false,
i,
len = publisher.length;

for(i = 0; i < len; i++) {
if (el === this) {
alreadyExists = true;
}
}

if (!alreadyExists) {
publisher.subscribers.push(this);
}

return this;
};

// 订阅者具有退订能力
Function.prototype.unSubscribe = function(publisher) {
var that = this,
array = [],
len = publisher.length;

for(i = 0; i < len; i++) {
if (el !== this) {
array.push(this);
}
}

publisher.subscribers = array;

return this;
};

三、现实世界中的观察者

  在现实世界中,观察者模式对于那种由许多JavaScript程序员合作开发的大型应用程序特别有用。它可以提高API的灵活性,使并行开发的多个市县能够彼此独立的进行修改。作为开发人员,你可以对自己的应用程序中什么是“令人感兴趣的时刻”做出决定。你所能监听的不再只是click、load、blur和mouseover等浏览器事件。在富用户界面应用程序中,drag(拖动)、drop(拖放)、moved(移动)、complete(完成)和tabSwitch(标签切换)都可能是令人感兴趣的事件。它们都是在普通浏览器事件的基础上抽象出来的可观察事件,可由发布者对象向其监听者广播。

  在DOM脚本编程环境中的高级时间模式中,事件监听器说到底就是一种内置的观察者。事件处理器(handler)与事件监听器(listener)并不是一回事。前者说穿了就是一种把事件传递给与其关联的函数的手段。而且在这种模型中一种事件只能指定一个回调方法。而在监听器模式中,一个事件可以与几个监听器关联。每个监听器都能独立于其他监听器而改变。


// 使用事件监听器,可以让多个函数响应同一个事件
var element = $(‘#example‘);
var fn1 = function(e) {
// handle clikc
};
var fn2 = function(e) {
// do other stuff with click
};
// 由于使用的是事件监听器,所以click事件发生时fn1和fn2都会被调用
addEvent(element, ‘click‘, fn1);
addEvent(element, ‘click‘, fn2);
// 但用事件处理器就办不到
var element = $(‘#example‘);
var fn1 = function(e) {
// handle clikc
};
var fn2 = function(e) {
// do other stuff with click
};
element.onclick = fn1;
// 第二个onclick赋值的结果是fn1被fn2取代,因此click事件发生时只会调用fn2。
element.onclick = fn2;

  监听器和观察者之间的共同之处显而易见。实际上它们互为同义词。它们都订阅特定的事件,然后等待事件的发生。事件发生时,订阅方的回调函数会得到通知。传给它们的参数是一个事件对象,其中包含着事件发生时间、事件类型和事件发源地等有用的信息。

四、优势

  观察者模式可以削减为事件注册监听器的次数,让可观察对象借助一个事件监听器替你处理各种行为并将信息委托给它的所有订阅者,从而降低内存消耗和提高互动性能,提高程序的可维护性。

五、劣势

  使用这种观察者接口的一个不利之处在于创建可观察对象所带来的加载时间开销。这可以通过惰性加载技术加以化解。

六、小结

  一个事件可以被5个订阅者订阅,而一个订阅者也可以订阅5个不同的事件。对于浏览器这类互动环境来说这非常理想。现在的Web应用程序越来越大,在此背景下,作为一种提高代码的可维护性和简洁性的有力手段,可观察对象的作用更显突出。

【读书笔记】读《JavaScript设计模式》之观察者模式,布布扣,bubuko.com

时间: 2024-10-20 17:11:01

【读书笔记】读《JavaScript设计模式》之观察者模式的相关文章

读书笔记之 - javascript 设计模式 - 接口、封装和链式调用

javascript 采用设计模式主要有下面的三方面原因: 可维护性:设计模式有助于降低模块之间的耦合程度.这使代码进行重构和换用不同的模块变得容易,也使程序员在大型项目中合作变得容易. 沟通:设计模式为处理不同类型的对象提供了一套通用的术语.程序员可以简洁的描述自己系统的工作方式. 性能:采用一些优化性能的模式,可以大幅度提高程序的执行效率,如享元模式和代理模式等 同时,滥用设计模式也会带来一些后果: 复杂性:代码变得复杂,新手难以理解 性能:多数设计模式会或多或少的降低代码的性能 实现容易,

【读书笔记】大话设计模式 1【2014-7-28】

大 大话设计模式这本书给我最大的感觉就是这本书不是为了说明设计模式而写的,它是为了让你能够更好地看懂,更好地理解而存在.到现在读了也有一半了,稍微总结一下. 0.uml类图. 软件工程的基础就是uml类图.依赖:元素A的变化会影响元素B,但反之不成立,那么B和A的关系是依赖关系,B依赖A:用带箭头的虚线表示,箭头指向被依赖元素.泛化:通常所说的继承(特殊个体 is kind of 一般个体)关系,不必多解释了.uml中用带空心箭头的实线线表示,箭头指向一般个体.实现:这个关系最常用于接口.uml

【读书笔记】大话设计模式 2【2014-7-31】

这本书慢慢的诚意让我没有任何理由不把它阅读完.学校有软件工程这门选修课,但是我感觉看了这本书比选那门课要好得多.里面的故事虽然没有跌宕起伏,但是生活中淡淡的趣味让我读完之后仍然有一种想看续集的冲动.希望学到的这些在我以后的道路上扮演重要的角色! 按照最后一章模式总结的顺序来总结一下: 1.创建型模式 抽象工厂 建造者模式(和工厂的区别:一个在于产生,一个在于组装)(和组合更是两码事了,组合是树形的,不要望文生义~) 工厂方法 原型模式 单例模式(只允许一个stastic存在,把构造方法封死,然后

浅谈javascript单体【读javascript设计模式第五章节单体有感】

单体,整个运行环境就独有一份,最简单的一种单体就是一个把所有属性和方法都集中在一起的对象,区别于一般的字面量对象,一般字面量对象是对一个物体的描述,集合该物体所具有的一些属性和方法,而单体则包含更多的些逻辑在里面,单体的好处有,划分命名空间,如果用来作为网页包装器,可以使得页面所有变量都封装在一个对象里,大幅度减小网页里的全局变量, 代码如: common.js (function(wz){ $.extend({ init:function(){ var self = this; this.bi

浅谈javascript继承【读javascript设计模式第四章节继承有感】

javascript继承,无任是类式继承,原型式继承还是渗元式继承都是通过不同方法去围绕着prototype转,简单分析下三种不同继承方法是如何围绕prototype转的 一:类似继承,先上关键代码 function extend(subClass,supClass){ var fn = function(){}; fn.prototype = supClass.prototype; subClass.prototype = new fn(); subClass.prototype.constr

第九次读书笔记——读《代码整洁之道》有感

第九次读书笔记--读<代码整洁之道>有感 "相对于任何宏伟景愿,对细节的关注甚至是更为关键的专业的基础.首先,开发者通过小型实践获得可用于大型实践的技能和信用度.其次,宏伟建筑中最细小的部分,比如关不紧的门,有点没有铺平的地板,甚至是凌乱的桌面,都会将整个大局的魅力毁灭殆尽."看完了这本书,感觉书中的这句话是整本书的核心.个人感觉这本书给我带来的更多的不是能力上的提升,而是思想上对代码整洁有了整体的把握. 首先,这本书让我们在思想层面上认识到了代码整洁的必要性,只有思想有了

JavaScript设计模式之观察者模式(学习笔记)

设计模式(Design Pattern)对于软件开发来说其重要性不言而喻,代码可复用.可维护.可扩展一直都是软件工程中的追求!对于我一个学javascript的人来说,理解设计模式似乎有些困难,对仅切图.做少量交互效果的FE甚至可能不会用到,但是当你开始使用Angular/Backbone等框架的时候,就无法避免设计模式.MVC/MVVM这些东西了(反正我是伤脑筋). 我学设计模式是刚开始接触编程大概三个月的时候,看一本书<大话设计模式>,里面用C#语言来写,我很无语,因为强类型的编程语言对于

Javascript设计模式之观察者模式

首先说一下观察者模式的应用场景 观察者的使用场合就是:当一个对象的改变需要同时改变其它对象,并且它不知道具体有多少对象需要改变的时候,就应该考虑使用观察者模式.(Tom大叔) 具体说一下这个观察者模式,就是一个发报纸的过程.我们订阅了报纸,在报社的数组里加上我们的名字(不仅是名字了是一个带我们名字的处理函数),这是订阅事件:报社才不管你订没订报纸,他只管给他数组里的人发报纸:我们在编码的时候只监听发报纸的事件,订不订报纸,谁订报纸,都是你的事,就不在放在监听的事件里了,于是就有了减少监听的优化:

读书笔记:javascript高级技巧(一)

一.安全的类型检测 javascript内置的类型检测机制并非完全可靠,由于浏览器或者作用域等原因,经常会发生错误.大家知道,在任何值调用toString()方法都会返回一个[object Native ConstructorName]格式的字符串,每个类内部都有一个[class]属性,这个属性就指定了上述字符串中的构造函数名.例如 var value=[1,2,3,4,5] alert(Object.prototype.toString.call(value));//"[object Arra

【读书笔记】javascript 继承

在JavaScript中继承不像C#那么直接,C#中子类继承父类之后马上获得了父类的属性和方法,但JavaScript需要分步进行. 让Brid 继承 Animal,并扩展自己fly的方法. function Animal(name) { this.name = name; this.type = "animal"; } Animal.prototype= { say:function() { alert("I'm a " + this.type + ",