发布订阅模式实现及发布订阅者模式与观察者模式的不同

Posted jlfw

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了发布订阅模式实现及发布订阅者模式与观察者模式的不同相关的知识,希望对你有一定的参考价值。

概念

发布订阅者模式,是javascript甚至大多数语言都有的语言模式,比较概念的解释是,

订阅者把自己想订阅的事件注册到调度中心,当该事件触发时候,发布者发布该事件到调度中心(第三方),由调度中心统一调度订阅者注册到调度中心的处理代码。

优缺点

优点
1.一对多。
一个发布者可以绑定多个订阅者,当事件触发时,由调度中心全部通知。
2.解耦。
发布订阅者模式中,订阅者是不知道也不关心事件是为什么触发,是由哪一个事件触发,只知道事件触发时候,会告诉自己。发布者也不用一一通知,只要告诉调度中心,事件触发了就好了。所以代码松耦合。
3.程序便于扩展。
缺点:
实现方式麻烦?

举例

用平时身边的例子解释,比如你被阿里邀请面试,面试完你问面试官什么时候出结果,面试官告诉你结果出来时候会通知你的,这样你就不用天天打电话问面试结果了,等面试结果出来,面试官会把面试结果统一发邮件给面试者,当你收到面试结果后,进行下一步操作,是到阿里上班,还是面试下一家。

代码实现

var observer = function () {
    var _observer = {};     
    let _queue = {};     // 所有事件的队列
    /**
    * @param 注册的事件名称
    * @param 事件触发时执行的函数
    */
    _observer.on = function (eventName, fn) {
        if (Object.prototype.toString.call(fn) !== ‘[object Function]‘) return;
        if (_queue[eventName] && _queue[eventName].length > 0) {
            // 如果之前注册过eventName事件
            _queue[eventName].push(fn);
        } else {
            // 之前没有注册过eventName事件
            _queue[eventName] = [fn];
        }
    },
     /**
    * @param 已经触发的事件(发布事件)
    */
    _observer.trigger = function (triggerEventName) {
        var args = Array.prototype.slice.call(arguments,1);
        if (!_queue[triggerEventName]) return;
        for (var i = 0; i < _queue[triggerEventName].length; i++) {
            _queue[triggerEventName][i].apply(null, args);
        }
    },
    // 移除注册事件
    _observer.remove = function (removeEventName) {
        for(var k in _queue) {
            if (k === removeEventName) {
                delete _queue[k];
            }
        }
    }
    // 移除所有注册事件
    _observer.removeAll = function () {
        _queue = {};
    }
    return _observer;
}()

发布订阅者模式与观察者模式区别

发布订阅者模式与观察者模式是很相似的,之前的好多网站、博客上也把它们画上等号,但是我前段时间接到一个面试,问我,发布订阅者模式与观察者模式有什么却别,当时说一样的,结果面试管说其实不一样,好吧,一脸懵逼,结束时候自己查阅了一下,确实不太一样。

区别

  • 在观察者模式中,观察者是知道Subject的,Subject一直保持对观察者进行记录。然而,在发布订阅模式中,发布者和订阅者不知道对方的存在。它们只有通过调度中心进行通信。
  • 在发布订阅模式中,组件是松散耦合的,正好和观察者模式相反。
  • 观察者模式大多数时候是同步的,比如当事件触发,Subject就会去调用观察者的方法。而发布-订阅模式大多数时候是异步的(使用消息队列)

举个例子
观察者模式就像你没有经验却买了比特币或者股票,然后害怕赔钱一直盯着k线图,一有变化立马就知道了,然后做下一步操作,是观望是买是抛都可以,熟悉vue的同学应该知道watch这个方法吧,对,就是观察者模式,国外有一图拿过来给你们看看
技术图片

参考

1.观察者模式 vs 发布-订阅模式
2.Observer vs Pub-Sub











以上是关于发布订阅模式实现及发布订阅者模式与观察者模式的不同的主要内容,如果未能解决你的问题,请参考以下文章

Java实现观察者(发布-订阅)模式

观察者模式与发布订阅模式的区别

设计模式-观察者模式 实现

从发布-订阅模式到消息队列

发布-订阅者模式 (观察者模式)

观察者模式