javascript观察者模式

西风.烈马 西风.烈马     2022-08-01     230

关键词:

      观察者模式又叫发布-订阅模式,它定义对象间的一对多的依赖关系,当一个对象的状态发生该变时,所有依赖于它的对象都将得到通知。在JavaScript中,一般用事件模型来替代传统的观察者模式。
     下面是售楼处(发布者)与各看房者(订阅者)的例子:
     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),
                         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 && (fns.length = 0);
                      }else{
                           for(var l=fns.length-1; l>=0; l--){ //反向遍历订阅的回调函数列表
                                var _fn = fns[l];
                                if(_fn ===fn){
                                      fns.splice(l,1); //删除订阅者的回调函数
                                }
                           }
                       }
            }
     };

 

     var installEvent = function(obj){ //给所有对象动态安装发布-订阅功能
          for(var i in event){
               obj[i] = event[i];
          }
      };

 

      var salesOffices = {}; //定义售楼处
      installEvent(salesOffices);

 

      salesOffices.listen(‘squareMeter100‘,function(price){ // 张三订阅消息
            console.log(‘价格=‘ + price);
      });

      salesOffices.listen(‘squareMeter150‘,function(price){ // 李四订阅消息
            console.log(‘价格=‘ + price);
      });

 

      salesOffices.trigger(‘squareMeter100‘,2000000); // 输出 2000000
      salesOffices.trigger(‘squareMeter150‘,3000000); // 输出 3000000

 


      上面的代码还存在两个小问题:
           1.每个发布者对象都添加了listen和trigger方法,以及一个缓存列表clientList,这是一种资源浪费
           2.订阅者跟售楼处对象存在一定的耦合性,订阅者至少要知道售楼处对象的名字是salesOffices,才能订阅到事件

      下面是对以上两个问题的改良:

      var event = {
           var clientList:[],
           listen,
           trigger,
           remove;

 

           listen = function(key,fn){
                if(!clientList[key]){
                     clientList[key] = [];
                }
               clientList[key].push(fn); //订阅的消息添加进缓存列表
            };

 

           trigger = function(){ //发布消息
                var key = Array.prototype.shift.call(arguments),
                fns = 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 = clientList[key];
                   if(!fns){ //如果key对应的消息没有被人订阅,则直接返回
                        return false;
                   }
                   if(!fn){ //如果没有传入具体的回调函数,表示需要取消key对应消息的所有订阅
                       fns && (fns.length = 0);
                   }else{
                       for(var l=fns.length-1; l>=0; l--){ //反向遍历订阅的回调函数列表
                            var _fn = fns[l];
                            if(_fn ===fn){
                                   fns.splice(l,1); //删除订阅者的回调函数
                            }
                       }
                  }
             };

            return {
                   listen:listen,
                   trigger:trigger,
                   remove:remove
            };
     };

 

     Event.listen(‘squareMeter150‘,function(price){ // 李四订阅消息
              console.log(‘价格=‘ + price);
     });

 

      Event.trigger(‘squareMeter150‘,2000000); // 输出 2000000


      改良后,发布-订阅模式可以用一个全局的Event对象来实现,订阅者不需要了解消息来自哪个发布者,发布者也不需要了解消息会推送给哪些订阅者,Event作为类似“中介者”的角色,把订阅者和发布者联系起来。

 

      观察者模式的优点非常明显,一为时间上的解耦,二为对象间的解耦。它的应用非常广泛,既可以用在异步编程中,也可以用来编写更松耦合的代码编写。但也不是没有缺点。创建订阅者本身要消耗一定的时间和内存,而且当你订阅一个消息后,也许此消息始终都没发生,但这个订阅者会始终存在于内存中。另外,观察者模式虽然可以弱化对象间的联系,但如果过度使用的话,对象间的必要联系也将被深藏在背后,会导致程序难以跟踪维护和理解。特别是有多个发布者和订阅者嵌套到一起的时候,要跟踪一个bug不是键轻松的事。

 

javascript订阅-发布模式(观察者模式)(代码片段)

查看详情

javascript设计模式——观察者模式

观察者模式,又称发布-订阅模式或消息机制,定义了一种依赖关系,解决了主题对象与观察者之间功能的耦合。通过运用观察者模式,可以解决团队开发中的模块间通讯问题,这是模块间解耦的一种可行方案。首先,我们来把... 查看详情

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

varEvent=(function(){varglobal=this,Event,_default=‘default‘;Event=function(){var_create,_listen,_trigger,_remove,_shift=Array.prototype.shift,_unshift=Array.prototype.unshift,namespaceCache={},each=f 查看详情

javascript-观察者模式

观察者模式方法  1.称之为消息机制或发布-订阅者模式  2.定义了一种依赖关系解决了主体对象与观察者之间功能的耦合观察者方法//将观察者放在闭包中,当页面加载就立即执行varObserver=(function(){var_messages={};return{... 查看详情

javascript---设计模式之观察者模式

概念观察者模式又叫发布订阅模式(Publish/Subscribe),它定义了一种一对多的关系,让多个观察者对象同时监听某一个主题对象,这个主题对象的状态发生变化时就会通知所有的观察者对象,使得它们能够自动更新自己。作用支... 查看详情

javascript观察者模式(再次)(代码片段)

查看详情

javascript观察者模式

...状态发生该变时,所有依赖于它的对象都将得到通知。在JavaScript中,一般用事件模型来替代传统的观察者模式。   下面是售楼处(发布者)与各看房者(订阅者)的例子:   varevent={    查看详情

深入理解javascript系列(32):设计模式之观察者模式

介绍观察者模式又叫公布订阅模式(Publish/Subscribe),它定义了一种一对多的关系。让多个观察者对象同一时候监听某一个主题对象。这个主题对象的状态发生变化时就会通知全部的观察者对象,使得它们可以自己主动更新自己... 查看详情

javascript观察者行为设计模式(代码片段)

查看详情

javascript设计模式观察者模式

观察者模式又叫发布订阅模式(Publish/Subscribe),它定义了一种一对多的关系,让多个观察者对象同时监听某一个主题对象,这个主题对象的状态发生变化时就会通知所有的观察者对象,使得它们能够自动更新自己。举个例子,... 查看详情

javascript设计模式与开发实践–观察者模式

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

javascript模块,单例和观察者模式(代码片段)

查看详情

javascript原生实现观察者模式

观察者模式又叫做发布订阅模式,它定义了一种一对多的关系,让多个观察者对象同时监听某一个主题对象,这个主题对象的状态发生改变时就会通知所有观察着对象。它是由两类对象组成,主题和观察者,主题负责发布事件,... 查看详情

观察者模式——javascript

观察者模式又被称为发布-订阅模型或消息机制。基本思想是观察者一个静态(或全局)对象,为大家提供三个方法:发布、订阅、取消订阅。想得到消息的订阅者需要通过订阅某些消息,当发布者发布某些消息的时候对应的订... 查看详情

javascript设计模式--行为型--设计模式之observer观察者模式(19)(代码片段)

         JAVASCRIPT设计模式是本人根据GOF的设计模式写的博客记录。使用JAVASCRIPT语言来实现主体功能,所以不可能像C++,JAVA等面向对象语言一样严谨,大部分程序都附上了JAVASCRIPT代码,代码只是实现了... 查看详情

javascript与php观察者模式

JAVASCRIPT:a.代码:vara=function(){this.int=0this.add=function(int){this.int=int}this.watch=function(){if(this.int==0){console.log(‘0‘)}else{console.log(‘not0‘)}}}vara=newa()a.watch()a.add(1)a.watch()b.输 查看详情

javascript设计模式--行为型--设计模式之observer观察者模式(19)(代码片段)

         JAVASCRIPT设计模式是本人根据GOF的设计模式写的博客记录。使用JAVASCRIPT语言来实现主体功能,所以不可能像C++,JAVA等面向对象语言一样严谨,大部分程序都附上了JAVASCRIPT代码,代码只是实现了... 查看详情

javascript设计模式与开发实践–观察者模式http://web.jobbole.com/87809/

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