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

通过运用观察者模式,可以解决团队开发中的模块间通讯问题,这是模块间解耦的一种可行方案。

首先,我们来把观察者对象创建处理,它有一个消息容器和三个方法,分别是订阅消息方法、发送订阅消息的方法和取消订阅消息的方法。如下:  

// 将观察者放在闭包中,当页面加载就立即执行
var Observer = (function () {
// 将消息容器做为静态私有变量,防止消息队列泄露而被篡改
var _messages = {}; return {
regist: function () {}, // 注册消息
fire: function () {}, // 发布消息
remove: function () {} // 取消消息
};
})();

现在,观察者的雏形已经出来了,我们接下来的事情就是一步步实现这三个方法。

1. 注册消息的作用是将订阅者的消息推入到消息队列中,因此我们需要接受两个参数:消息类型和相应的处理动作。

在推入到消息队列时,如果此消息不存在则应该创建一个消息类型并将该消息放入消息队列中;如果此消息存在则应该将消息执行方法推入改消息对应的执行方法队列中,这么做的目的是保证多     个模块注册同一则消息时能顺利执行。  

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

2. 发布消息的功能是,当观察者发布一个消息时,会将所有订阅者订阅的消息依次执行。故应该接受两个参数:消息类型和动作执行时要传递的参数。

在执行消息动作队列之前对消息存在的校验是很有必要的,然后遍历消息执行方法队列,并依次执行。

fire: function (type, args) {
if (!_messages[type]) {
return;
}; var events = {
type: type,
args: args || {}
}; for (var i = 0, len = _messages[type].length; i < len; i++) {
_messages[type][i].call(this, args);
};
},

3. 注销消息的功能是将订阅者注销的消息从消息队列中清除掉,因此我们可以传递两个参数:消息类型和动作函数。

  如果只传递消息类型参数,则注销所有订阅此消息类型的动作函数,

  若两者都传递,则只注销此消息类型的当前传递参数的动作函数。

  当然为了避免删除消息动作时消息不存在的情况出现,对消息队列中消息的存在性校验也是很有必要的。

remove: function (type, fn) {
if (!fn) {
_messages[type] = null;
return;
}; if (_messages[type] instanceof Array) {
var i = _messages[type].length - 1;
for (; i >= 0; i--) {
_messages[type][i] === fn && _messages[type].splice(i, 1);
};
}
}

至此,观察者模式就实现完啦!可以稍微测试一下:

var fn1 = function () {
console.log(1);
}
var fn2 = function () {
console.log(2);
}
Observer.regist('test', fn1);
Observer.regist('test', fn2); Observer.fire('test'); // 1 2
Observer.remove('test', fn1);
Observer.fire('test'); // 2

JavaScript设计模式——观察者模式的更多相关文章

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

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

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

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

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

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

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

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

  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. Flume入门:安装、部署

    一.什么是Flume? flume 作为 cloudera 开发的实时日志收集系统,受到了业界的认可与广泛应用.Flume 初始的发行版本目前被统称为 Flume OG(original genera ...

  2. ERP,SCM,CRM,BRP,OMS,WMS 企业管理的6大核心系统

    [导读]:人体共有八大系统:运动系统.神经系统.内分泌系统.循环系统.呼吸系统.消化系统.泌尿系统.生殖系统.这些系统协调配合,使人体内各种复杂的生命活动能够正常进行. 同理,企业要想健康的运转,长久 ...

  3. windows系统同时连接多个openvpn账户

    windows系统同时连接多个openvpn账户. 前提 客户端系统:Windows7 64位 OpenVPN版本:OpenVPN 2.3.10 Windows 64位 一.安装 1.安装目录 D:\ ...

  4. ubuntu截图工具

    ubuntu截图工具   首先,我们用apt-get  install 去安装一个,scrot 主要用在命令行下,它使用 imlib2 库来抓取并保存图像                 sudo a ...

  5. 把一个一中的字段更新另一个表中的t-sql

    UPDATE dbo.CommDescr SET Descr=(SELECT ba.content FROM dbo.blog_article ba WHERE ba.id=3) WHERE Comm ...

  6. python--标准库 时间与日期 (time, datetime包)

    Python具有良好的时间和日期管理功能.实际上,计算机只会维护一个挂钟时间(wall clock time),这个时间是从某个固定时间起点到现在的时间间隔.时间起点的选择与计算机相关,但一台计算机的 ...

  7. ExecuteScalar,ExecuteReader,ExecuteNonQuery区别

    ExecuteScalar is typically used when your query returns a single value. If it returns more, then the ...

  8. layui数据表格自定义每页条数limit

    table.render({ elem: '#data_grid' //,width: 900 //,height: 274 ,cols: [[ //标题栏 {field: 'id', title: ...

  9. Ubuntu中建立ftp 503错误解决办法

    The problem is because your folder is owned by root, instead of ftpuser. To fix it run: sudo chown - ...

  10. C++不让程序一闪而过

    末尾加上System("pause") 不过需要注意,这个只在win32下有效.不具备可移植性.