【读书笔记】读《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设计模式》之观察者模式的更多相关文章
- 再起航,我的学习笔记之JavaScript设计模式18(观察者模式)
观察者模式 观察者模式(Observer): 又被称为发布-订阅者模式或消息机制,定义了一种依赖关系,解决了主体对象与观察者之间功能的耦合. 创建一个观察者对象 首先我们创建一个闭包对象,让其在页面加 ...
- 读书笔记之 - javascript 设计模式 - 观察者模式
在事件驱动的环境中,比如浏览器这种持续寻求用户关注的环境中,观察者模式是一种管理人与其任务(确切的讲,是对象及其行为和状态之间的关系)之间的关系的得力工具.用javascript的话来讲,这种模式的实 ...
- 读书笔记之 - javascript 设计模式 - 接口、封装和链式调用
javascript 采用设计模式主要有下面的三方面原因: 可维护性:设计模式有助于降低模块之间的耦合程度.这使代码进行重构和换用不同的模块变得容易,也使程序员在大型项目中合作变得容易. 沟通:设计模 ...
- 读书笔记之 - javascript 设计模式 - 命令模式
本章研究的是一种封装方法调用的方式.命令模式与普通函数有所不同.它可以用来对方法调用进行参数化处理和传送,经过这样处理过的方法调用可以在任何需要的时候执行. 它也可以用来消除调用操作的对象和实现操作的 ...
- 读书笔记之 - javascript 设计模式 - 代理模式
代理(proxy)是一个对象,它可以用来控制对另一对象的访问.它与另外那个对象实现了同样的接口,并且会把任何方法调用传递给那个对象.另外那个对象通常称为本体.代理可以代替本体被实例化,并使其可被远程访 ...
- 读书笔记之 - javascript 设计模式 - 享元模式
本章探讨另一种优化模式-享元模式,它最适合于解决因创建大量类似对象而累及性能的问题.这种模式在javascript中尤其有用,因为复杂的javascript代码很快就会用光浏览器的所有可用内存,通过把 ...
- 读书笔记之 - javascript 设计模式 - 门面模式
门面模式有俩个作用: 简化类的接口 消除类与使用它的客户代码之间的耦合 在javascript中,门面模式常常是开发人员最亲密的朋友.它是几乎所有javascript库的核心原则,门面模式可以使库提供 ...
- 读书笔记之 - javascript 设计模式 - 单体模式
单体是一个用来划分命名空间,并将一批相关方法和属性组织在一起的对象,如果它可以被实例化,那么它只能被实例化一次. 单体模式,就是将代码组织为一个逻辑单元,这个逻辑单元中的代码可以通过单一的变量进行访问 ...
- 读书笔记之 - javascript 设计模式 - 组合模式
组合模式是一种专为创建Web上的动态用户界面而量身定制的模式,使用这种模式,可以用一条命令在对各对象上激发复杂的或递归的行为. 在组合对象的层次体系中有俩种类型对象:叶对象和组合对象.这是一个递归定义 ...
- 读书笔记之 - javascript 设计模式 - 工厂模式
一个类或者对象中,往往会包含别的对象.在创建这种对象的时候,你可能习惯于使用常规方式,即用 new 关键字和类构造函数. 这会导致相关的俩个类之间产生依赖. 工厂模式,就是消除这俩个类之间的依赖性的一 ...
随机推荐
- AndroidManifest File Features
http://www.android-doc.com/guide/topics/manifest/manifest-intro.html The following sections describe ...
- linux 下安装memcached与php的memcache扩展
1. 在线安装 yum install memcached: 源代码安装 wget http://memcached.org/latest 下载最新版本 tar -zxvf memcached-1.x ...
- 百度或者Google---SEO优化(转载)
google 和百度的技术差别: 1.百度还认不清哪个是原创的 2.google蜘蛛不够百度快 4.google排名结果随时变化 流量.权重.权威.内容.用户体验.用户关注度等等细节的排名,已表 达了 ...
- C# 检测操作系统是否空闲,实现系统空闲后做一些操作
public class CheckComputerFreeState { /// <summary> /// 创建结构体用于返回捕获时间 /// </summary> [St ...
- log4j:ERROR setFile(null,true) call failed.java.io.FileNotFoundException: ..\logs\2010-1-19.log (系统找不到指定的路径。)
log4j:ERROR setFile(null,true) call failed.java.io.FileNotFoundException: ..\logs\2010-1-19.log (系统找 ...
- ubuntu系统 用户进入后命令行只有一个“$” 美元符号
在新添加用户后,切换到该用户下面后: 发现命令行前面只有一个$符号,很不方便. 虽然每次输入一个bash可以解决,但是太麻烦. 如何解决呢? sudo vi /etc/passwd 找到该用户 wan ...
- 将List<int> 转换为用逗号连接为字符串
List<, , , , }; string str = String.Join(",", testList.ConvertAll<string>(new Con ...
- POJ 3349 Snowflake Snow Snowflakes
Snowflake Snow Snowflakes Time Limit: 4000MS Memory Limit: 65536K Total Submissions: 27598 Accepted: ...
- HDOJ 1083 Courses
Hopcroft-Karp算法模板 Courses Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 65536/32768 K (J ...
- thinkphp中where方法
今天来给大家讲下查询最常用但也是最复杂的where方法,where方法也属于模型类的连贯操作方法之一,主要用于查询和操作条件的设置.where方法的用法是ThinkPHP查询语言的精髓,也是Think ...