美文网首页前端开发程序员
浅谈js的设计模式之订阅和发布

浅谈js的设计模式之订阅和发布

作者: 飘落的枫 | 来源:发表于2017-11-14 17:13 被阅读8次
概念

发布---订阅模式又叫观察者模式,它定义了对象间的一种一对多的关系,让多个观察者对象同时监听某一个主题对象,当一个对象发生改变时,所有依赖于它的对象都将得到通知

使用场景

当一个对象改变时同时改变其它对象,并且它不知道具体有多少对象需要改变的时候,就应该考虑使用观察者模式。

优点
  1. 支持简单的广播通信,当对象状态发生改变时,会自动通知已经订阅过的对象。
  2. 发布者与订阅者耦合性降低,职责单一,发布者只管负责发布消息,不用管订阅者如何实现,相对的订阅者只管负责处理自己的事情,不需要考虑发布者有哪些变化。
缺点

因为需要给发布者开辟一个内存去存储订阅者的信息,所以会有一定的内存开销。

实现订阅和发布模式
1.简洁版

var publishMessage = {};//定义对象用来进行数据的存储
//创建订阅者
function registEntiy(regist,callback){//regist:注册的事件名称,callback:回调函数
    if(!publishMessage[regist]){
       publishMessage[regist] = [];
    }
    publishMessage[regist].push(callback);
}

//创建发布者
function publishEntiy(regist,args){
     if(!publishMessage[regist]){
         return;
      }
    for(var i=0,lengths = publishMessage[regist].length;i<lengths;i++){
         publishMessage[regist][i](args);//执行回调
     }
          
}
//测试
//创建三个订阅者
registEntiy('step1',function(data){
   console.log('this is '+data.index);
})
registEntiy('step2',function(data){
   console.log('this is ' +data.index);
})
registEntiy('step3',function(data){
   console.log('this is '+data.index);
})
//发布者进行信息的发布
publishEntiy('step1',{index:1});.//this is 1
publishEntiy('step2',{index:2});.//this is 2
publishEntiy('step3',{index:3});.//this is 3

//小结
//通过如上代码相信大家已经理解订阅和发布模式的原理,简单来说就是开辟一个内存来存储用来处理的即将执行的事情,我们将其称为订阅者,好似订餐时的消费者,先点菜,我不管你怎么做的,只要做好了你给我送过来就好。在某一特定时间后通过订阅者的注册时的key来执行相应的回调,此时的发布者就是餐馆的服务员,他通过点菜是的号码,在菜做好之后,然后将菜送到对应的用餐者那里
2.封装版

上面的代码看起来比较零散,现在我们将其进行封装,并完善

function ObserverModel(){
    this.message = {};
}
 //发布者
ObserverModel.prototype.publish = function(){
       var key = Array.prototype.shift.call(arguments); //取出订阅者消息名称 
       var  fns = this.message[key];//取出该消息名称下的回调函数
       if(!this.message[key]){
          return;
       }
    for(var i = 0 ,lengths =fns.length;i<lengths ;i++ ) {
        fns[i].apply(this,arguments); // arguments 是发布消息时附送的参数
    }
}
//注册者
ObserverModel.prototype.regist = function(key,fn){
      if(!this.message[key]){
       this.message[key] = [];
    }
     this.message[key].push(fn);
}
//增加一个注销者
ObserverModel.prototype.remove = function(key){
   if(!this.message[key]){
     return
  }
  for(var i in this.message){
    if(this.message.hasOwnProperty(i)){
           if(i === key){
               this.message[i] = null;
              return;
            }
       }
    }
}
//测试
var  observer = new ObserverModel();
observer.regist('start',function(data){console.log('this is start '+data)});//订阅
observer.publish('start',2);//发布
//结果
this is start 2
observer.regist('start',function(data){console.log('this is start '+data)});//订阅
observer.remove('start');//退订订阅者
observer.publish('start',2);//发布
//结果
没有回调函数执行,说明退订成功
3.运用项目中

在我们项目中经常会进行ajax请求然后执行相关的回调函数,现在让我们运用这种模式来进行优化,看如下代码

//场景 在初始化的时候,客户端需要通过服务端传回的数据进行渲染页面,如 拿到数据后要进行l两个模块的渲染如下
function renderPage1(data){
   ......
}
function renderPage2(data){
   ......
}
//常规方法
$.ajax('get',url,function(data){renderPage1(data);renderPage2(data)});
//此时每当我们需要增加一个渲染函数时,我们都有在ajax执行成功的回调函数进行增加一个指向函数,这样耦合性就会很高,不利于以后的维护
//采用观察者模式,使用我们刚刚封装的方法
var  observer = new ObserverModel();
observer.regist('success',renderPage1);//注册
observer.regist('success',renderPage2);//注册
$.ajax('get',url,function(data){observer.publish('success',data));//发布
//这种写法耦合性就会很低
4总结

订阅和发布模式也称作观察者模式,其使用的场景在于一个对象的变化会导致多个对象的响应改变,原理是利用内存通过键值的方式进行先行存储即订阅,然后当这一个对象变化时进行去执行内存中存储的信息,根据键去查找相应的值然后执行相应的订阅者,优点是耦合性低,可以用作信息的广播。

相关文章

网友评论

    本文标题:浅谈js的设计模式之订阅和发布

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