您的位置:首页 > 其它

模式学习⑧--观察者模式

2013-12-31 15:43 176 查看
var publisher = {

// 一个由数组组成的集合
subscribers : {
any : []// 事件类型: 订阅者(subsribes)
},

// 将订阅者加入数组 // subscribers : { any : [fn], weekly : [fn], monthly : [fn]}
subscribe : function(fn, type){
type = type || 'any';
if(typeof this.subscribers[type] === "undefined"){
console.log("this ::",this);
this.subscribers[type] = [];
}
this.subscribers[type].push(fn); //any ->  [fn] /  weekly -> [fn] / monthly -> [fn]
// console.log("this.subscribers[type]     ",this.subscribers["any"]);
// console.log("this.subscribers[type]     ",this.subscribers["monthly"]);
},

// 从数组中删除订阅者
unsubscribe : function(fn, type){
this.visitSubscribers('unsubscribe', fn, type);
},

// 遍历订阅者并调用它们订阅时提供的方法
publish : function(publication, type){
this.visitSubscribers('publish', publication, type);
},
visitSubscribers : function(action, arg, type){ // action = 'publish' ,arg = publication = "big news today"
var pubtype = type || 'any',
subscribers = this.subscribers[pubtype],// subscribe得到的数组[fn]
i,
max = subscribers.length;
for(i = 0; i < max; i++){
if(action === 'publish'){
// console.log("arg:", arg)
subscribers[i](arg); // 执行 fn()
}else{  
if(subscribers[i] === arg){
subscribers.splice(i, 1);
}
}
}
}
};

function makePublisher(o){
var i;
for(i in publisher){
if(publisher.hasOwnProperty(i) && typeof publisher[i] === "function"){
o[i] = publisher[i];
}
}
o.subscribers = {any : []};
}

// 实现paper对象,它所能做的就是发布日报和月刊
var paper = {
daily : function(){
this.publish("big news today");
},
weekly : function(){
this.publish("big news in a week", 'weekly');
},
monthly : function(){
this.publish("interesting analysis", "monthly");
}
};

// 将paper对象变成发布者:
makePublisher(paper);

// 订阅者对象joe
var joe = {
drinkCoffee : function(paper){
console.log("Just read " + paper);
},
dinner : function(weekly){
console.log("Just read " + weekly);
},
sundayPreNap : function(monthly){
console.log("About to fall asleep reading this " + monthly);
}
};

// 现在,paper注册joe
paper.subscribe(joe.drinkCoffee);
paper.subscribe(joe.dinner, 'weekly');
paper.subscribe(joe.sundayPreNap, 'monthly');

paper.daily();
paper.weekly();
paper.monthly();
paper.daily();
paper.daily();
paper.monthly();

makePublisher(joe);
joe.tweet = function(msg){
this.publish(msg);
};

paper.readTweets = function(tweet){
console.log("Call big meeting! Someone " + tweet);
};
joe.subscribe(paper.readTweets);

joe.tweet("hates the paper today");

 joe.tweet("loves the paper today");


说明:

  1. 将发布publish作为单独的Object,再借用Makepublisher()方法, 可以使得paper, joe, xx , oo 都能成为发布者。

  2. subscribers 在这里是类似于 { any : [fn], weekly : [fn], monthly : [fn]} 这样的object. 里面的 any weekly monthly 都是type类型。(any是默认的)

  3. A - MakePublisher(xx), 让xx成为发布者

    B - xx.subscribe(oo); oo 可以是另一个观察者的方法-既是订阅

   C - 发布:调用publish()方法

  4. 其中的访问订阅者visitSubscribers ,用来 -发布/删除- 订阅者

    publication 是发布的内容,subscribers = this.subscribers[pubtype] - 获取发布者的type对应的 订阅者要执行的函数 相当于 1 中的[fn], subScribers[i](arg) ,但其实这里的arg又是引用的发布者的内容, 就是根据发布的类型执行了订阅者本身的函数(参数是发布的内容)。

  5. A 可以给 B发布,B也可以给A发布。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: