美文网首页
设计模式--发布订阅

设计模式--发布订阅

作者: 一包 | 来源:发表于2019-04-03 17:04 被阅读0次

    发布订阅

    • 订阅发布模式定义了一种一对多的依赖关系,让多个订阅者对象同时监听某一个主题对象。这个主题对象在自身状态变化时,会通知所有订阅者对象,使它们能够自动更新自己的状态。
    • 首先要想好谁是发布者(比如上面的卖家)。
    • 然后给发布者添加一个缓存列表,用于存放回调函数来通知订阅者(比如上面的买家收藏了卖家的店铺,卖家通过收藏了该店铺的一个列表名单)。
    • 最后就是发布消息,发布者遍历这个缓存列表,依次触发里面存放的订阅者回调函数。
    var event ={
        clientlist:{},
        //添加订阅对象
        listen:function(key,fn){
            if(!this.clientlist[key]){
               //如果没有订阅过此类消息,创建一个缓存列表 this.clientlist[key]=[];
            }  
            this.clientlist[key].push.fn;
        },
        trigger:function(){
                //绑定发布事件
            var key=Array.prototype.shift.call(arguments);//从原数组中去掉第一位,并且返回
            var fns=this.clientlist[key];
            if(!fns||fns.length==0) return false;
            for(var i=0,fn;fn=fns[i++]){
                fn.apply(this,arguments);
            }
            
        },
        remove:function(key,fn){
            var fns=this.clientlist[key];
            if(!fns){
                //如果key对应的消息没有被订阅,直接返回
                return false;
            }
            if(!fn){
                //如果没有传入具体对应的回调函数,表示取消key对应消息的所有订阅
                fns=[]
            }else{
                for(let index=0;index<fns.length;index++){
                    var _fn=fns[index];
                    if(_fn==fn){
                        fns.splice(index,1)
                    }
                }
            }
            
        }
    }
    var installEvent=function(obj){
        for(var i in event){
            obj[i] = event[i];
        }
    }
    
    var saleOffices = {};
    installEvent( saleOffices );
           saleOffices.listen( "squareMeter88", fn1 = function( price ){
               console.log( "价格" + price );
           } );
           saleOffices.listen( "squareMeter88", function( price ){
               console.log( "价格" + price );
           } );
           saleOffices.remove( "squareMeter88", fn1 );
           saleOffices.trigger( "squareMeter88", 200000 );
    
    --------------------- 
    作者:夏岭 
    来源:CSDN 
    原文:https://blog.csdn.net/hi_xiexialing/article/details/54645242 
    版权声明:本文为博主原创文章,转载请附上博文链接!
    
    var event = {
        list: [],
        listen: function(key,fn) {
            if(!this.list[key]) {
                this.list[key] = [];
            }
            // 订阅的消息添加到缓存列表中
            this.list[key].push(fn);
        },
        trigger: function(){
            var key = Array.prototype.shift.call(arguments);
            var fns = this.list[key];
            // 如果没有订阅过该消息的话,则返回
            if(!fns || fns.length === 0) {
                return;
            }
            for(var i = 0,fn; fn = fns[i++];) {
                fn.apply(this,arguments);
            }
        },
      remove:function(key,fn){
        var fns=this.list[key];
        if(!fns){
          //对应key事情没有被订阅
          return false;
        }
        if(!fn){
          //如果没有对应没有传入的函数,则表示全部清空
          fns=[];
        }else{
          for(var i=0;i<fns.length;i++){
            if(fns[i]==fn){
              fns.splice(i,1);
            }
          }
        }
      },
      once:function(key,fn){
        function one(){
          fn.apply(this,arguments);
          this.remove(key,one);
        }
        this.listen(key,one);
        
      }
    };
    var initEvent = function(obj) {
        for(var i in event) {
            obj[i] = event[i];
        }
    };
    // 我们再来测试下,我们还是给shoeObj这个对象添加发布-订阅功能;
    var shoeObj = {};
    initEvent(shoeObj);
    
    // 小红订阅如下消息
    shoeObj.once('red',fn1=function(size){
        console.log("尺码是:"+size);  
    });
    shoeObj.listen('red',fn1=function(size){
        console.log("尺码dierci");  
    });
    // 小花订阅如下消息
    shoeObj.listen('block',fn2=function(size){
        console.log("再次打印尺码是:"+size); 
    });
    shoeObj.remove("block",fn2);  
    
    shoeObj.trigger("red",40);
    shoeObj.trigger("block",42);
    
    
    
    
    

    发布订阅,观察区别

    • 区别

    • 在观察者模式中,观察者是知道Subject的,Subject一直保持对观察者进行记录。

    • 然而,在发布订阅模式中,发布者和订阅者不知道对方的存在。它们只有通过调度中心进行通信。

    • 在发布订阅模式中,组件是松散耦合的,正好和观察者模式相反。

    • 观察者模式大多数时候是同步的,比如当事件触发,Subject就会去调用观察者的方法。而发布-订阅模式大多数时候是异步的(使用消息队列)

    • 而发布订阅模式中统一由调度中心进行处理,订阅者和发布者互不干扰。这样一方面实现了解耦,还有就是可以实现更细粒度的一些控制。比如发布者发布了很多消息,但是不想所有的订阅者都接收到,就可以在调度中心做一些处理,类似于权限控制之类的。还可以做一些节流操作

    • 观察者模式中观察者和目标直接进行交互

    相关文章

      网友评论

          本文标题:设计模式--发布订阅

          本文链接:https://www.haomeiwen.com/subject/zcwzbqtx.html