观察者模式定义了一种一对多的关系,让多个观察者对象同时监听某一个主题对象,这个对象的状态发生变化时就会通知所有的观察者对象,使得它们能够自动更新自己。

UML示意图:

其中的角色:

Subject:主题角色把所有对观察考对象保存在一个对象里,每个主题都可以有任何数量的观察者。主题可以增加和删除观察者对象。并提供订阅和解除订阅的方法。

Observer:在得到主题的通知时更新自己。

例子:杂志订阅

主题角色包含一些对象和方法:

其中subscribers是按照每个类型创建一个数组来存储对应订阅者的一个对象,subscribe()是将对应订阅者添加到相应类型事件的订阅者数组中的方法。unsubscribe()删除订阅者,publish()遍历subscribers中的每个元素,调用他们注册时所提供的方法,type指的是事件的类型,比如出日刊和出月刊。

var publisher = {
subscribers:{
any:[] //type of event : subscribers
},
subscribe:function(fn,type){
type = type ||"any";
if(typeof this.subscribers[type] ==="undefined"){
this.subscribers[type] = [];
}
this.subsribers[type].push(fn);
},
unsubscribe:function(fn,type){
this.visitSubscribers("unsubscribe",fn,type);
},
publish:function(publication,type){
this.visitSubscribers("publish",publication,type);
},
visitSubscribers:function(function,arg,type){
var pubtype = type || "any",
subscribers = this.subscribers[pubtype],
i,
max = subscribers.length;
for(i=0 ; i<max ; i++){
if(action ==="publish"){
subscribers[i](arg);
}else{
if(subscribers[i] === arg){
subscribers.splice(i,1);
}
}
}
}
};

下面的函数接受一个对象,通过把上述发布者的方法复制到该对象,将其转化为一个发布者:

function makePublisher(o){
var i;
for(i in publisher){
if(publisher.hasOwnProperty(i)&&typeof[i] ==="function"){
o[i]=publisher[i];
}
}
o.subscribers={any:[]};
}

paper对象,发布日报和月刊:

var paper={
daily:function(){
this.publish("big news today");
},
monthly:function(){
this.publish("interesting things","monthly");
}
};

将paper构造成发行者:

makePublisher(paper);

订阅者joe:

var joe = {
drinkCoffee:function(paper){
console.log("Just read"+paper);
},
sundayPreNap:function(monthly){
console.log("About to fall asleep to read this"+monthly);
}
};

订阅:

paper.subscribe(joe.drinkCoffee);
paper.subscribe(joe.sundayPreNap,"monthly");

触发一些事件:

paper.daily();
paper.daily();
paper.daily();
paper.monthly();

输出:

Just read big news today
Just read big news today
Just read big news today
About to fall asleep reading this interesting things

这样分离的好处,是paper对象与joe对象是可以改动的,可以添加事件类型,可以添加订阅者的行为。甚至joe也可以成为发布者,在Twitter上发布状态更新:

makePublisher(joe);
joe.tweet = function(msg){
this.publish(msg);
};

paper可以收听joe的Twitter,订阅joe的信息,需要提供方法readTweets:

paper.readTweets = function(tweet){
console.log("Call big meeting!Someone"+tweet);
};
joe.subscribe(paper.readTweets);

现在,只要joe发出tweet消息,paper就会得到提醒:

joe.tweet("hated the paper today");

会输出:

"Call big meeting!Someone hated the paper today"

观察者的使用场合是:当一个对象的改变需要同时改变其它对象,并且它不知道具体有多少对象需要改变的时候,就应该考虑使用观察者模式。

观察者模式所做的工作就是在解耦,让耦合的双方都依赖于抽象,而不是依赖于具体。从而使得各自的变化都不会影响到另一边的变化。

javascript设计模式-观察者模式的更多相关文章

  1. javascript 设计模式-----观察者模式

    观察者模式在设计模式中被重点提到,因为它应用的场景非常多,而且在模块化设计当中扮演着非常重要的角色.MVC模式中最底层的就是观察者模式,当下流行的javascript框架backbone就是很好地运用 ...

  2. 读书笔记之 - javascript 设计模式 - 观察者模式

    在事件驱动的环境中,比如浏览器这种持续寻求用户关注的环境中,观察者模式是一种管理人与其任务(确切的讲,是对象及其行为和状态之间的关系)之间的关系的得力工具.用javascript的话来讲,这种模式的实 ...

  3. javaScript设计模式--观察者模式(observer)

    观察者模式(observer):又被称为 发布-订阅者模式或者消息机制,定义了一种依赖关系,解决了主体对象与观察者之间功能耦合. 一.这样的需求 在实现自己的需求,而添加一些功能代码,但是又不想新添加 ...

  4. JavaScript设计模式——观察者模式

    观察者模式,又称发布-订阅模式或消息机制,定义了一种依赖关系,解决了主题对象与观察者之间功能的耦合. 通过运用观察者模式,可以解决团队开发中的模块间通讯问题,这是模块间解耦的一种可行方案. 首先,我们 ...

  5. JavaScript 设计模式: 发布者-订阅者模式

    JavaScript 设计模式: 发布者-订阅者模式 发布者-订阅者模式 https://github.com/Kelichao/javascript.basics/issues/22 https:/ ...

  6. JavaScript设计模式与开发实践 - 观察者模式

    概述 观察者模式又叫发布 - 订阅模式(Publish/Subscribe),它定义了一种一对多的关系,让多个观察者对象同时监听某一个目标对象(为了方便理解,以下将观察者对象叫做订阅者,将目标对象叫做 ...

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

    设计模式(Design Pattern)对于软件开发来说其重要性不言而喻,代码可复用.可维护.可扩展一直都是软件工程中的追求!对于我一个学javascript的人来说,理解设计模式似乎有些困难,对仅切 ...

  8. 再起航,我的学习笔记之JavaScript设计模式18(观察者模式)

    观察者模式 观察者模式(Observer): 又被称为发布-订阅者模式或消息机制,定义了一种依赖关系,解决了主体对象与观察者之间功能的耦合. 创建一个观察者对象 首先我们创建一个闭包对象,让其在页面加 ...

  9. [转] JavaScript设计模式之发布-订阅模式(观察者模式)-Part1

    <JavaScript设计模式与开发实践>读书笔记. 发布-订阅模式又叫观察者模式,它定义了对象之间的一种一对多的依赖关系.当一个对象的状态发生改变时,所有依赖它的对象都将得到通知. 例如 ...

随机推荐

  1. 黄聪:走进wordpress do_action函数

    再看do_action函数.位于plugin.php352行.我把源码放在西街口这里,略去了其它辅助处理的语句. 如下: function do_action($tag, $arg = '') {   ...

  2. 黄聪:VPS实现自动定时备份网站数据以及Mysql数据库到百度云同步盘

    建站多了,备份成了头疼的问题,因为你不知道你的VPS什么时候会宕机或者服务商跑路,一旦网站数据丢失,那么相当于前功尽弃了,所以自己研究出了一套自动备份的方法. 需要的东西: 1.一个VPS(虚拟空间没 ...

  3. PUA

    约会技巧 kino技巧 被拒绝的应对方法 (1)一般约会7个小时后,就能带女生回家 (2)点菜时多点一点,以回家放菜为名 (3)理由要文雅 (4)开酒店的理由 第一时间触碰测试 (1)第一次约会要第一 ...

  4. c++学习-继承

    继承 #include <iostream> using namespace std; class father{ public: void getHeight(){cout<< ...

  5. 转-Fragment+FragmentTabHost组件(实现新浪微博底部菜单)

    http://www.cnblogs.com/lichenwei/p/3985121.html 记得之前写过2篇关于底部菜单的实现,由于使用的是过时的TabHost类,虽然一样可以实现我们想要的效果, ...

  6. 用友UAP

    1, 用友UAP 用友集团UAP中心成立于2013年1月1日,隶属于用友集团,旨在为全球大中型企业和公共组织提供计算平台,并打造完整.统一的软件产业链生态系统,以先进的平台.技术和专业的服务成为客户信 ...

  7. jquery源码

    null  与 undefined 都是  ==null 为true alert(typeof(123))  number alert(typeof(NAN))   打印 number 不靠谱 ale ...

  8. CentOS修改163源(转载)

    From:http://www.linuxidc.com/Linux/2012-08/69043.htm #CentOS-Base.repo其他版本文件在http://mirrors.163.com/ ...

  9. 无法创建spool文件

    是因为没有用管理员运行CMD,并且数据库不需要使用超级管理员登录.

  10. [ActionScript 3.0] AS3 时间格式化方法

    /** * 格式化时间,格式 00:00:00 * @param total 总时间(毫秒) */ function getFormatTime(total:uint):String { if (to ...