观察者模式(observer):又被称为 发布-订阅者模式或者消息机制,定义了一种依赖关系,解决了主体对象与观察者之间功能耦合。

一、这样的需求

在实现自己的需求,而添加一些功能代码,但是又不想新添加的代码影响他人的实现功能,也就是说,你不想让自己的模块与他人的模块严重耦合在一起,对于这类问题,观察者模式是比较理想的解决方案。

观察者模式可以解开我和他们之间的功能耦合。

观察者模式,也被人称为消息机制或者发布-订阅者模式。为了解决主体对象与观察者之间功能耦合

二、创建一个观察者

把观察者或者消息系统看作一个对象,那么他应该包含两个方法,一个是接受消息,一个是向中转站发送相应消息。

首先,我们把需要的把观察者对象创建出来,有一个消息容器和三个方法,分别是,订阅消息的方法,取消订阅消息的方法,发送订阅消息的方法。

var Observer = (function(){
//防止消息队列暴露而被篡改,所以将消息容器作为静态私有变量保存
var __messsages = {};
return {
//注册信息接口
regist: function(){},
//发布信息的接口
fire: function(){},
//移除信息接口
remove: function(){}
}
})();

观察者对象的雏形出来了,我们需要做的事情就是实现这三个方法,我们首先实现消息注册方法,注册方法的作用是将订阅者注册的消息推入到消息队列中,因此我们需要接受两个参数:消息类型和以及相应的处理动作,在推入到消息队列时如果此消息不存在应该创建一个该消息类型并将该消息放入到消息队列中,如果此消息存在则应该将消息执行方法推入该消息对应的执行方法队列中,这么做目的是保证多个模块注册同一个消息能顺利执行。

regist: function(type,fn){
//如果此消息不存在,则应该创建一个该消息类型
if(typeof __messages[type] === 'undefined'){
//将对象推入到该消息对应的动作执行队列中
__messages[type] = [fn];
//如果此消息存在
}else{
//将动作方法推入该消息对应的动作执行序列中
__messages[type].push(fn);
}
}

对于发布消息方法,其功能是当观察者发布一个消息时将所有订阅者订阅的消息一次执行。

故应该接受两个参数,消息类型以及动作执行时需要传递的参数,当然在这里消息类型是必须的。在执行消息队列之前校验消息的存在是很有必要的。

然后遍历消息执行方法队列,并依此执行。

然后将消息类别以及传递的参数打包后依次传入消息队列执行方法中。

fire: function(type,args){
//如果该消息没有被注册,则返回
if(!__messages[type]){
return ;
//定义消息信息
var events = {
type:type,
args:args||{}
},
i=0;
len = __messages[type].length;
for(;i<len;i++){
//依次执行注册的消息对应的动作序列
__messages[type][i].call(this,events);
}
}

最后是消息注册方法,其功能是将订阅者注销的消息从消息队列清除,因此我们也需要两个参数,即消息类型以及执行的某一个动作。当然为了避免删除消息动作时消息不存在情况的出现,对消息队列中消息的存在性校验也很有必要的。

remove:function(type,fn){
//如果消息动作队列存在
if(__messages[type] instanceof Array){
//从最后一个消息动作遍历
var i = __messages[type].length-1;
for(;i>=0;i--){
//如果存在该动作则在消息动作中移除相应动作
__messages[type][i] === fn && __messages[type].splice(i,1);
}
}
}

三、测试一下

观察者对象或者说,消息系统创建成功之后,简单测试一下:

首先订阅一条消息

Observer.regist('test',function(e){
console.log(e.type,e.args.msg);
});

然后,我们发布这则消息

Observer.fire('test',{msg:'传递参数'});   //test 传递参数

四、回忆一下

观察者模式最主要的作用的:解决类或对象之间的耦合,解耦两个相互依赖的对象,使其依赖于观察者的消息机制。

这样对于任意一个订阅者对象来说,其他订阅者对象的改变不会影响到自身。

对于每一个订阅者来说,其自身既可以是消息的发出者也可以是消息的执行者,这都依赖于调用观察者对象的三个方法(订阅消息,注销消息,发布消息)

javaScript设计模式--观察者模式(observer)的更多相关文章

  1. java设计模式--观察者模式(Observer)

    java设计模式--观察者模式(Observer) java设计模式--观察者模式(Observer) 观察者模式的定义: 定义对象间的一种一对多的依赖关系.当一个对象的状态发生改变时,所有依赖于它的 ...

  2. 设计模式-观察者模式(Observer Pattern)

    观察者模式(Observer Pattern):定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象.这个主题对象在状态发生变化时,会通知所有观察者对象,使他们能够自动更新自己. 观察者 ...

  3. 设计模式 - 观察者模式(Observer Pattern) 详细说明

    观察者模式(Observer Pattern) 详细说明 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26583157 版权全部 ...

  4. 设计模式 - 观察者模式(Observer Pattern) 详细解释

    观察者模式(Observer Pattern) 详细解释 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26583157 版权全部 ...

  5. 设计模式 - 观察者模式(Observer Pattern) Java内置 用法

    观察者模式(Observer Pattern) Java内置 用法 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26601659 ...

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

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

  7. 设计模式--观察者模式Observer(对象行为型)

    一.观察者模式 观察者模式是在对象之间定义一对多的依赖,这样一来,当一个对象改变状态,依赖它的对象都会收到通知,并自动更新.观察者模式也被称之为:主题-观察者模式,发布-订阅模式,前者是一,后者是多. ...

  8. 大话设计模式--观察者模式 Observer -- C++ 实现实例

    大话设计模式--1.观察者模式: 定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象,这个主题对象在状态发生变化时,会通知所有的 观察者对象,使他们能够自动更新自己. 使用场合: 当一 ...

  9. [工作中的设计模式]观察者模式observer

    一.模式解析 观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象.这个主题对象在状态上发生变化时,会通知所有观察者对象,使它们能够自动更新自己. 观察者模式又叫订阅发布模式, ...

随机推荐

  1. 【莫比乌斯反演】BZOJ2820 YY的GCD

    Description 求有多少对(x,y)的gcd为素数,x<=n,y<=m.n,m<=1e7,T<=1e4. Solution 因为题目要求gcd为素数的,那么我们就只考虑 ...

  2. BZOJ_1040_[ZJOI2008]骑士_树形DP

    BZOJ_1040_[ZJOI2008]骑士_树形DP 题意: Z国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英.他们劫富济贫,惩恶扬善,受到社会各 界的赞扬.最近发生了一件可怕的事情,邪 ...

  3. aes 128、192、256位,cbc、cfb、ecb、ofb、pcbc加密解密

    AES加解密总共有以下这些 算法/模式/填充 字节加密后数据长度 不满16字节加密后长度 AES/CBC/NoPadding 16 不支持 AES/CBC/PKCS5Padding 32 16 AES ...

  4. C语言文件 "w+"与"wb+"区别

    这是我今天碰到的问题,现在已经解决, 希望我的整理能够帮助到你们! w+以纯文本方式读写,而wb+是以二进制方式进行读写. mode说明: w 打开只写文件,若文件存在则文件长度清为0,即该文件内容会 ...

  5. Shell脚本的三种执行方式

    Shell脚本的执行方式可以有以下几种: 方式一:  ./script.sh # 利用小数点来执行 方式二:  sh script.sh 或 bash script.sh # 利用bash(sh)来执 ...

  6. python接口自动化(二十四)--unittest断言——中(详解)

    简介 上一篇通过简单的案例给小伙伴们介绍了一下unittest断言,这篇我们将通过结合和围绕实际的工作来进行unittest的断言.这里以获取城市天气预报的接口为例,设计了 2 个用例,一个是查询北京 ...

  7. 小白学习Python之路---re模块学习和挑战练习

    本节大纲: 1.正则表达式 2.re模块的学习 3.速记理解技巧 4.挑战练习--开发一个简单的python计算器 5.心得总结 6.学习建议 正则表达式: 正则表达式,又称规则表达式.(英语:Reg ...

  8. zabbix微信报警信息优化模板

    --------------------------------告警模板1-------------------------------------- 默认标题 告警项目: {TRIGGER.NAME ...

  9. React 虚拟 DOM 的差异检测机制

    React 使用虚拟 DOM 将计算好之后的更新发送到真实的 DOM 树上,减少了频繁操作真实 DOM 的时间消耗,但将成本转移到了 JavaScript 中,因为要计算新旧 DOM 树的差异嘛.所以 ...

  10. xamarin forms常用的布局StackLayout详解

    通过这篇文章你将了解到xamarin forms中最简单常用的布局StackLayout.至于其他几种布局使用起来,效果相对较差,目前在项目中使用最多的也就是这两种布局StackLayout和Grid ...