推荐阅读http://dev.housetrip.com/2014/09/15/decoupling-javascript-apps-using-pub-sub-pattern/

我们先引出问题的所在,这里使用一个订单系统:

在一个电子商务系统中,现在我们有订单模块,和信息模块两个主要模块,当下单成功时,我们用要发送订单信息的给客户。

下面是一个简单的解决办法,我们在一个类中调用另一个类的方法。

// 订单类,存储订单的所有变量和函数
function Order( goods ){
this.goods = goods;
}
Order.prototype = {
done: function(){
// 订单完成代码
this.sendSuccessMsg();
},
sendSuccessMsg: function(){
var message = new Message();
message.sendMsg(this.goods)
}
} // 消息类,具备各种消息功能函数
function Message(){}
Message.prototype = {
sendMsg: function( goods ){
alert("商品名:"+goods.name+"\n"+"价格:"+goods.price);
}
//其它信息模块的方法
}
var order = new Order({ name:"索尼耳机", price:100})
order.done() //弹出商品的信息

经过简单的分析代码,我们可以发现一些问题,首先,Order和Message紧耦合,一般来说,当一个类进行的修改会需要另一个类的修改这就是耦合。在这里,比较直接的一个问题,当我们改改了Message类中的sendMsg方法的名字或者参数时,Order类中的相应函数名和参数也要跟着修改。

知道了这种方法的问题,下面我们就来看看如何用Publish/Subscribe模式改进这段代码.Publish/Subscribe模式是一种消息通信模式,信息发布一方叫发布者,信息的接收方叫订阅者。

下面是一个根据Publish/Subscribe模式的简易系统

var subpub = {};
(function( subpub ){
var list = {};
subpub.publish = function(topic,msg){
for(var i = 0; i<list[topic].length; i++) {
list[topic][i](msg);
}
}
subpub.subscribe = function( topic,listener){
if(!list[topic]) list[topic] = [];
list[topic].push(listener);
}
})( subpub ) // 测试
subpub.subscribe('foo', function(msg){
alert(msg);
});
subpub.publish('foo', 'Hello World!')

将这个事件管理小系统应用到之前的订单系统中,进行解耦。

function Order( goods ){
this.goods = goods;
}
Order.prototype = {
done: function(){
// 订单完成代码
this.sendSuccessMsg();
},
sendSuccessMsg: function(){
subpub.publish('order/done',this.goods);
}
}
function Message(){
subpub.subscribe('order/done',this.sendMsg);
}
Message.prototype = {
sendMsg: function( goods ){
alert("商品名:"+goods.name+"\n"+"价格:"+goods.price);
}
//其它信息模块的方法
}
var message = new Message();
var order = new Order({ name:"索尼耳机", price:100});
order.done() //弹出商品的信息

现在,我们发现Message和Order类不关心彼此是如何实现的。修改某个类中的函数也不用考虑是否会影响到另一个类,就比如我们想修改sendMsg的函数名,只需要对Message进行修改,不会影响到Order。我们唯一需要关心的一点知识保存的事件名。

总结一下,Publish/Subscribe模式是用特定的事件名将函数存放在一个列表之中,通过这个特定的事件名,我们可以在任意处调用函数,并传入参数。

他使得类与类之间的耦合度减少,尤其是当一个类需要调用好多个类中的方法。

javascript设计模式——Publish/Subscribe的更多相关文章

  1. Publish/Subscribe Pattern & Vanilla JavaScript

    Publish/Subscribe Pattern & Vanilla JavaScript https://en.wikipedia.org/wiki/Publish–subscribe_p ...

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

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

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

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

  4. javaScript 设计模式系列之一:观察者模式

    介绍 观察者模式又叫发布订阅模式(Publish/Subscribe),一个目标对象管理所有相依于它的观察者对象.该模式中存在两个角色:观察者和被观察者.目标对象与观察者之间的抽象耦合关系能够单独扩展 ...

  5. JavaScript设计模式:读书笔记(未完)

    该篇随我读书的进度持续更新阅读书目:<JavaScript设计模式> 2016/3/30 2016/3/31 2016/4/8 2016/3/30: 模式是一种可复用的解决方案,可用于解决 ...

  6. JavaScript的学习--JavaScript设计模式的总结

    这篇博客只是自己对设计模式的理解的备忘~ 看完了<JavaScript设计模式>这本书,一直没有写博客记录一下,最近抽出时间来重读了一下,就顺便记录一下~ 如果你只是想粗略了解一下Java ...

  7. 浅谈Javascript设计模式

    什么是模式 模式是一种可复用的解决方案,可用于解决软件设计中遇到的常见问题. 也就是说用来解决常见问题的可复用的解决方案. 常见的js设计模式 Constructor(构造器)模式 Construct ...

  8. RabbitMQ入门教程(五):扇形交换机发布/订阅(Publish/Subscribe)

    原文:RabbitMQ入门教程(五):扇形交换机发布/订阅(Publish/Subscribe) 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. ...

  9. 《JavaScript设计模式 张》整理

    最近在研读另外一本关于设计模式的书<JavaScript设计模式>,这本书中描述了更多的设计模式. 一.创建型设计模式 包括简单工厂.工厂方法.抽象工厂.建造者.原型和单例模式. 1)简单 ...

随机推荐

  1. [每日一题] OCP1z0-047 :2013-08-18 禁用启用约束――主键与外键 ..................................61

    正确答案:C 根据题意,测试结果如下: 1.创建表emp,并且设emp_no字段为主键,设mgr_no字段为外键. gyj@MYDB> create table emp 2 (emp_no nu ...

  2. Android_Fragment_Fragment具体解释

    Android_Fragment_Fragment具体解释 分类: Android基础2013-10-03 08:23 92人阅读 评论(0) 收藏 举报 AndroidFragmentFragmen ...

  3. [生成树][Uva1395][Slim Span]

    代码: #include <set> #include <queue> #include <cmath> #include <cstdio> #incl ...

  4. 关于ASP.NET 中站点地图sitemap 的使用

    在ASP.NET  MVC 如此火热的时期,我竟然不适时宜的谈起ASP.NET ,恐怕会引来一阵嘲笑.最为无趣的是,讲解的竟然还是其中的一个控件.oh~~  my god!my out! ^_^ Si ...

  5. locate: can not stat () `/var/lib/mlocate/mlocate.db': No such file or directory

    安装好CentOS后,第一次进入系统使用locate命令,结果出现:locate: can not stat () `/var/lib/mlocate/mlocate.db': No such fil ...

  6. QJson 的使用

    下载 源码解压 https://github.com/flavio/qjson 复制 src 目录下所有 .h .cpp .hh 文件到项目目录 qjson,pro 文件添加 INCLUDEPATH ...

  7. 用jquery制作加载条

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  8. Error:Execution failed for task ':app:mergeDebugResources'. > Some file crunching failed, see logs for details

    Android Studio 编译中断.... Error:Execution failed for task ':app:mergeDebugResources'. > Some file c ...

  9. C# 当前程序所有线程

    using System.Linq; var threads = System.Diagnostics.Process.GetCurrentProcess().Threads;var count = ...

  10. python笔记之Cmd模块

    python笔记之Cmd模块 Cmd类型提供了一个创建命令行解析器的框架,默认情况下,它使用readline来进行交互式操作.命令行编辑和命令完成. 使用cmd创建的命令行解释器循环读取输入的所有行并 ...