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

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. 20个超实用的JavaScript技巧及最佳实践

    1.第一次给变量赋值时,别忘记var关键字   给一个未声明的变量赋值,该变量会被自动创建为全局变量,在JS开发中,应该避免使用全局变量.   2.使用===替换==   并且永远不要使用=或!=. ...

  2. python 虎扑注册检查脚本

    ulipad,看着蛮舒服的. 图里的代码就是今天晚上的成果. 突然就想看看python这个被很多人说是优雅的语言,于是晚上没事就配了配环境,做了个东西 #encoding: utf-8 import ...

  3. AP_AP系列 - 付款管理分析(案例)

    2014-07-08 Created By BaoXinjian 一.摘要 1. 付款 2. 发票付款概述 3. 使用发票工作台付款 4. 使用付款管理器付款 5. 银行账户模型 二.流程分析 1. ...

  4. 关于maven的一些常见用法

    1: 查看插件的目标信息:mvn help:describe 2: 生成javadoc并指定编码:mvn javadoc:javadoc -Dencoding=UTF-8 -Dcharset=UTF- ...

  5. http请求的referer属性

    HTTP Referer是header的一部分,当浏览器向web服务器发送请求的时候,一般会带上Referer,告诉服务器我是从哪个页面链接过来的,服务器籍此可以获得一些信息用于处理.比如从我主页上链 ...

  6. CentOS配置网卡,重启网络显示:Device does not seem to be present(转载)

    From:http://www.cnblogs.com/fbwfbi/archive/2013/04/29/3050907.html 一.故障现象: [root@c1node01 ~]# servic ...

  7. 区分DPI、分辨率(PPI)、图像的物理大小、像素宽度

    分辨率都知道,越高越清晰. 一.描述分辨率的单位有:    dpi(点每英寸).lpi(线每英寸)和ppi(像素每英寸).但只有lpi是描述光学分辨率的尺度的.虽然dpi和ppi也属于分辨率范畴内的单 ...

  8. Replace JSON.NET with ServiceStack.Text in ASP.NET Web API

    Because ServiceStack.Text performs much better I recently stumbled across a comparison of JSON seria ...

  9. Java中的Property类

    Property是JAVA中的属性操作类,该类在java.util包中,它是HashTable的子类. 常用函数列表: l  Properties() n  构造函数 l  setProperty(S ...

  10. [SQL]SQL语言入门级教材_SQL语言快速入门(五)

    SQL语言快速入门(一) SQL是英文Structured Query Language的缩写,意思为结构化查询语言. SQL语言的主要功能就是同各种数据库建立联系,进行沟通.按照ANSI(美国国家标 ...