Javascript设计模式之观察者模式

首先说一下观察者模式的应用场景

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

具体说一下这个观察者模式,就是一个发报纸的过程。我们订阅了报纸,在报社的数组里加上我们的名字(不仅是名字了是一个带我们名字的处理函数),这是订阅事件;报社才不管你订没订报纸,他只管给他数组里的人发报纸;我们在编码的时候只监听发报纸的事件,订不订报纸,谁订报纸,都是你的事,就不在放在监听的事件里了,于是就有了减少监听的优化;

我们来构建一下观察者API

首先我们设置一个报社:

1 function Publisher(){
2   this.subscribers = [];//报社存放关于订阅者的数组
3 }

 

下面实现报社发报纸:

1 Publisher.prototype.deliver = function(data) {//记住哦,发报纸是deliver方法,里面是报纸内容的参数
2   this.subscribers.forEach(function(fn){
3     fn(data);
4   })
5   return this;
6 };

好,下面是订阅方法,当然,所有人想订阅就订阅,方法加在Function的原型链上:

Function.prototype.subscribe = function(publisher){
  var this = that;
  var alreadyExists = publisher.subscribers.some(function(el){
    return el === that;
  });
  if ( !alreadyExists) {
    publisher.subscribers.push(this);
  };
  return this;
}

 

数组的some方法,和foreach的回调形式差不多,不过只要有一次调用回调函数就会返回true否则为false;

退订方法:

Function.prototype.unsubscribe = function(publisher){
  var this = that;
  publisher.subscribers = publisher.subscribers.filter(function(el){
    return el !== that;
  })
  return this;
}

 

这里数组的filter方法,返回符合条件的数组,遍历数组,如果他的某一元素不等于这“我”,就返回其他。相当于数组的shift(“我”)方法;

至此API完了。这玩意怎么用呢。

举一个动画的例子;

var Animation = function(o){
  this.onStart = new Publisher,
  this.onComplete = new Publisher,
  this.onTween = new Publisher;
 };
Animation.prototype.fly = funciton(){
  this.onStart.deliver();
  for(...){//这里遍历所有的组织
    this.onTween.deliver(i);
  }
  this.onComplete.deliver();
} 
var Superman = new Animation({})//设置特性
var pushOnCape = function(i){};//这里添加处理事件
var takeOfCape = function(i){};//这里添加处理事件
pushOnCape.subscribe(Superman.onStart);
takeOfCape.subscribe(Superman.onComplete);
//然后,这个fly写哪都行
$('div').addEventListener('click',function(){
  Superman.fly();
})

 

说明:

这里监听一个click,让报社发报纸。发给谁用谁订阅。比如pushOnCape、和takeOfCape都

调用了subscribe方法,加入一个事件就让他订阅就行;

这里的subscribe方法传递一个onStart相当于start报社,还有另外两家报社,他们分别发自己的报纸,想订谁的

报纸就订阅哪家的报社;

当点击div的时候。调用了fly方法,各个报社开始发自己的报纸(deliver),报社查看自己的订阅者数组[],发现

 pushOnCape、takeOfCape调用过subscribe方法,加入到数组了,就给他发消息了;消息是data,这里没啥用,不过

 this.onTween.deliver(i);这里可以区分i,主要是发送消息到他自己,这里是pushOnCape、takeOfCape,于是调用它们自己的函数

 function(i){}如注释,->这里添加处理事件,其实是触发click的时候各个部分进行的动作;

总结一下:

观察者模式的作用就是将各种行为和信息都给他的自己,用subscribe方法来做,削减监听器的数量,减低内存消耗,

提高互动性能;

它的坏处就是创建可观察对象带来的时间消耗,不过你可以在用它的时候再实例化它,程序初始化的时候就不会有影响;

首先说一下观察者模式的应用场景

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

具体说一下这个观察者模式,就是一个发报纸的过程。我们订阅了报纸,在报社的数组里加上我们的名字(不仅是名字了是一个带我们名字的处理函数),这是订阅事件;报社才不管你订没订报纸,他只管给他数组里的人发报纸;我们在编码的时候只监听发报纸的事件,订不订报纸,谁订报纸,都是你的事,就不在放在监听的事件里了,于是就有了减少监听的优化;

我们来构建一下观察者API

首先我们设置一个报社:

function Publisher(){

this.subscribers = [];//报社存放关于订阅者的数组

}

下面实现报社发报纸:

Publisher.prototype.deliver = function(data) {//记住哦,发报纸是deliver方法,里面是报纸内容的参数

this.subscribers.forEach(function(fn){

fn(data);

})

return this;

};

给基础不好的同学讲一下,forEach传递两个参数得时候第一个参数是数组内容,第二个参数是index,这里的fn是

代表数组里“我”的处理;我还为怎么传进来fn纠结了一阵,是被匿名函数蒙蔽了双眼;返回this,让他能够连续调用,能

连续不断的投送数据;

好,下面是订阅方法,当然,所有人想订阅就订阅,方法加在Function的原型链上:

Function.prototype.subscribe = function(publisher){

var this = that;

var alreadyExists = publisher.subscribers.some(function(el){

return el === that;

});

if ( !alreadyExists) {

publisher.subscribers.push(this);

};

return this;

}

数组的some方法,和foreach的回调形式差不多,不过只要有一次调用回调函数就会返回true否则为false;

退订方法:

Function.prototype.unsubscribe = function(publisher){

var this = that;

publisher.subscribers = publisher.subscribers.filter(function(el){

return el !== that;

})

return this;

}

这里数组的filter方法,返回符合条件的数组,遍历数组,如果他的某一元素不等于这“我”,就返回其他。相当于数组的shift(“我”)方法;

至此API完了。这玩意怎么用呢。

举一个动画的例子;

var Animation = function(o){

this.onStart = new Publisher,

this.onComplete = new Publisher,

this.onTween = new Publisher;

};

Animation.prototype.fly = funciton(){

this.onStart.deliver();

for(...){//这里遍历所有的组织

this.onTween.deliver(i);

}

this.onComplete.deliver();

var Superman = new Animation({})//设置特性

var pushOnCape = function(i){};//这里添加处理事件

var takeOfCape = function(i){};//这里添加处理事件

pushOnCape.subscribe(Superman.onStart);

takeOfCape.subscribe(Superman.onComplete);

然后,这个fly写哪都行

$('div').addEventListener('click',function(){

Superman.fly();

})

说明:

这里监听一个click,让报社发报纸。发给谁用谁订阅。比如pushOnCape、和takeOfCape都

调用了subscribe方法,加入一个事件就让他订阅就行;

这里的subscribe方法传递一个onStart相当于start报社,还有另外两家报社,他们分别发自己的报纸,想订谁的

报纸就订阅哪家的报社;

当点击div的时候。调用了fly方法,各个报社开始发自己的报纸(deliver),报社查看自己的订阅者数组[],发现

 pushOnCape、takeOfCape调用过subscribe方法,加入到数组了,就给他发消息了;消息是data,这里没啥用,不过

 this.onTween.deliver(i);这里可以区分i,主要是发送消息到他自己,这里是pushOnCape、takeOfCape,于是调用它们自己的函数

 function(i){}如注释,->这里添加处理事件,其实是触发click的时候各个部分进行的动作;

总结一下:

观察者模式的作用就是将各种行为和信息都给他的自己,用subscribe方法来做,削减监听器的数量,减低内存消耗,

提高互动性能;

它的坏处就是创建可观察对象带来的时间消耗,不过你可以在用它的时候再实例化它,程序初始化的时候就不会有影响;

posted @ 2015-11-26 20:44  chenby  阅读(348)  评论(0编辑  收藏  举报