观察者模式(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. Oracle中的instr()函数

    一.instr()函数 1.语法:instr(sourceString,destString,start,appearPosition) sourceString代表源字符串; destString代 ...

  2. 【强连通分量】Bzoj1051 HAOI2006 受欢迎的牛

    Description 每一头牛的愿望就是变成一头最受欢迎的牛.现在有N头牛,给你M对整数(A,B),表示牛A认为牛B受欢迎. 这种关系是具有传递性的,如果A认为B受欢迎,B认为C受欢迎,那么牛A也认 ...

  3. HTTP VISUAL HTTP请求可视化工具、HTTP快照工具(公测)

    先啰嗦几句,最近工作比较忙,再加上自己又开设了一个小站(简单点),没时间写博客,都快憋坏了,趁着周末有时间,抓紧来一篇~ HTTP VISUAL是一款HTTP可视化工具,它可以记录HTTP请求,包括请 ...

  4. ELK 架构之 Elasticsearch、Kibana、Logstash 和 Filebeat 安装配置汇总(6.2.4 版本)

    相关文章: ELK 架构之 Elasticsearch 和 Kibana 安装配置 ELK 架构之 Logstash 和 Filebeat 安装配置 ELK 架构之 Logstash 和 Filebe ...

  5. Python 视频转字符画 - 进阶

    这篇文章是 视频转字符动画-Python-60行代码 的后续,如果感兴趣,请先看看它. 1. 速度优化 要是每次播放都要等个一分钟,也太痛苦了一点. 所以可以用 pickle 模块把 video_ch ...

  6. Mui Webview下来刷新上拉加载实现

    有些事情经历过之后才会发现,原来再次之前我是如此的啥,因为是第一次做,毫无头绪,有时会想假如有个一demo就好了,那么就不会花费这么多的无用功了.今天使用mui 的webview实现了一个H5页面的上 ...

  7. RabbitMQ指南之一:"Hello World!"

    为什么要使用MQ消息中间件?它解决了什么问题?关于为什么要使用消息中间件?消息中间件是如何做到同步变异步.流量削锋.应用解耦的?网上已经有很多说明,我这里就不再说明了,读者可以参考(https://w ...

  8. 『这是一篇干货blog』

    更新记录一些很好的干货博客以及工具网站. 各文章,工具网站版权归原作者所有,侵删. Articles 浅谈C++ IO优化--读优输优方法集锦 浅谈斜率优化 思维导图好助手--开心食用Xmind Ty ...

  9. 【推荐】 HyperLedger Fabric环境搭建、测试及注意事项 [详尽指导] [亲测有效]

    系统:Ubuntu16.04 LTS 一.环境准备 1.1 Ubuntu下安装 crul sudo apt install curl curl是利用URL语法在命令行方式下工作的开源文件传输工具.它被 ...

  10. Python3|ddt|unittest|浅议数据驱动测试

    目录 1.DDT简介 2.data装饰器 3.unpack装饰器 4.file_data装饰器 5.总结 1.DDT简介 Data-Driven Tests(DDT)即数据驱动测试.它允许您通过不同的 ...