Javascript实现 设计模式之发布-订阅模式

前言


一个多月前,面试时被问到发布-订阅模式,面试完就查阅资料学习了下。这篇文章我将记录我对此的理解并用Javascript代码实现发布-订阅模式。

介绍


用一个全局对象,负责模块间的通信,具体落实发布和订阅两种功能。发布者不需要知道订阅者,订阅者不需要知道发布者,发布者能启动功能器使订阅者收到消息,这就足够了

优势


1、统一管理

订阅模式中,可以抽离出调度中心单独成一个文件,可以对一系列的订阅事件进行统一管理。

2、松耦合

发布者不需要知道订阅者的数量,订阅者听得话题或者订阅者是通过什么方式运行的。他们能够相互独立地运行,这样就可以让你分开开发这两部分而不需要担心对状态或实现的任何细微的影响。

缺点


1、状态未知

发布者不知道订阅者的状态,反之亦然,这样的话,你根本不知道在另一端是否会没有问题?

2、不能识别恶意消息

攻击者(恶意的发布者)能够入侵系统并且撕开它。这会导致恶意的消息被发布,订阅者能够获得他们以前并不能获得的消息。

3、关系更新难

更新发布者和订阅者的关系会是一个很难的问题,因为毕竟他们根本不认识对方。

代码实现

1、发布-订阅模块实现
//publish-subscribe.js

var publishEvents = (function () {
    var listen,log,obj, one, remove, trigger, __this;
    obj = {};
    __this = this;
    listen = function( key, eventfn ) {  // 订阅
        var stack, _ref;
        stack = ( _ref = obj[key] ) != null ? _ref : obj[ key ] = [];
        return stack.push( eventfn );
    };
    one = function( key, eventfn ) { //只能被一个订阅者订阅
        remove( key );
        return listen( key, eventfn );
    };
    remove = function( key ) {  // 解除
        var _ref;
        return ( _ref = obj[key] ) != null ? _ref.length = 0 : void 0;
    };
    trigger = function() {   // 发布
        var fn, stack, _i, _len, _ref, key;
        key = Array.prototype.shift.call( arguments );
        stack = ( _ref = obj[ key ] ) != null ? _ref : obj[ key ] = [];
        for ( _i = 0, _len = stack.length; _i < _len; _i++ ) {
            fn = stack[ _i ];
            if( fn == undefined ) return false;
            if ( fn.apply( __this,  arguments ) === false) {
                return false;
            }
        }
    }
    return {
        listen: listen,
        one: one,
        remove: remove,
        trigger: trigger
    }
})();

module.exports = publishEvents;
2、模块使用
//test-publish-subscribe.js

var pubSub = require('./publish-subscribe');

var testStr = 'testStr';

pubSub.listen(testStr, function() {
    console.log('pubSub.listen');
});

setTimeout(function() {
    console.log('1秒后的 pubSub.trigger')
    pubSub.trigger(testStr);
    pubSub.remove(testStr);
}, 1000);

setTimeout(function() {
    console.log('2秒后的 pubSub.trigger');
    pubSub.trigger(testStr);
}, 2000);
3、结果
运行结果

最后

如果有疑问,请下载示例代码,也可以欢迎私信或者留言给我。
如果觉得对你有帮助,请点个👍,谢谢

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 173,641评论 25 708
  • 工厂模式类似于现实生活中的工厂可以产生大量相似的商品,去做同样的事情,实现同样的效果;这时候需要使用工厂模式。简单...
    舟渔行舟阅读 7,881评论 2 17
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,009评论 19 139
  • 发布/订阅模式又叫观察者模式,它定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都...
    风铭阅读 2,716评论 0 1
  • 有很多人说:如果你没有在年轻的时候谈过几场恋爱,那么你何来青春,既然年轻,总要为那么一两个人奋不顾身。是的...
    何heyiwen阅读 215评论 2 1