关于设计模式大家应该不陌生吧,今天我正好在看组件的时候看到有关于设计模式的东西,所以决定写下来以供以后学习和复习,不然脑子总是喜欢忘掉啊
设计模式有很多种,什么观察者模式,职责链模式,工厂模式等等,今天先谈谈观察者模式
观察者模式又叫做订阅者模式,按字面意思理解,就类似于订阅杂志,我订阅了某个刊物,只要有新的期出现,发布刊物者就会通知我我就会知道,因为我订阅了。那么这种设计模式在我们程序设计中有啥用呢,比如,我们在设计网站的时候,有可能有这么一个需求,就是只要用户已登录,某几个模块就要干嘛干嘛,那么模块如何在用户登录完成的时候知道呢,这里我们就可以用观察者模式了,这某几个模块可以订阅用户登录事件,一旦用户登录完成就会通知这几个订阅模块,这几个模块就知道,哦用户已经登录了,那么久可以完成后续事件。
好了,应用场景就这样了。现在我们来想想怎么实现呢
首先我们得定义一个发布对象,然后要有订阅者,那么发布者怎么把消息通知给订阅者呢,或者说消息是给这个订阅者的某个属性呢还是某个方法,我是发布者我怎么知道具体是哪个方法呢?这就要求订阅者在订阅的时候其实是要将自己接受消息的函数也注册进来的,这样的话,发布者就知道了,我发布消息时候,订阅者的某个函数就要接受消息并做执行。
发布对象大概有哪些成员你应该知道了吧
1、首先是subscribes:一个数组,存储订阅者的某个方法的
2.subscribe()注册事件,或者是订阅事件,将订阅者的某个方法推送到1中的数组中
3.unsubscribe():取消订阅,从1说的数组中删除
4.publish()循环遍历1中的数组,并且调用他们注册时候所提供的方法
现在先用字面量的方法来实现下:
定义一个对象,代码如下:
<!DOCTYPE html>
<html>
<script>
//定义一个对象publisher(),
var publisher={
subscribers:{
default:[],
},
subcribe:function(fn,type){
var type=type||'default';
if(typeof this.subscribers[type]==='undefined'){
this.subscribers[type]=[];
}
this.subscribers[type].push(fn);
},
dissubcribe:function(fn,type){
var type = type || 'default';
if(typeof this.subscribers[type]==='undefined'){
this.subscribers[type]=[];
}
for(var i=0;i<this.subscribers[type].length;i++){
if(this.subscribers[type][i]===fn){
this.subscribers[type].splice(i,1);
}
}
},
publish:function(arg,type){
var type = type || 'default';
if(this.subscribers[type]==='undefined'){
this.subscribers[type]=[];
}
for(var i=0, len = this.subscribers[type].length; i<len; i++){
this.subscribers[type][i](arg);
}
}
};
//定义一个函数makePublisher(),作用复制对象的方法,接受一个对象作为对象,通过把上述通用发布者的方法复制到该对象中,从而将其转换为一个发布者
function makepublisher(obj){
var i;
for(i in publisher){
if(publisher.hasOwnProperty(i)&&typeof publisher[i]==='function'){
obj[i]=publisher[i];
}
}
obj['subscribers'] = {'default':[]};
};
</script>
</html>
用代码测试下:
var firstpublisher={
first:function(news){
this.publish(news);
},
second:function(news){
this.publish(news,'night');
}
};
makepublisher(firstpublisher);
var Jack={
morning:function(news){
console.log('jack read'+news+'at morning');
},
night:function(news){
console.log('jack read'+news+'at night');
}
};
var Rose={
morning:function(news){
console.log('Rose read'+news+'at morning');
},
night:function(news){
console.log('Rose read'+news+'at night');
}
};
firstpublisher.subcribe(Jack.morning);
firstpublisher.subcribe(Jack.night, 'night');
firstpublisher.subcribe(Rose.night, 'night');
firstpublisher.subcribe(Rose.morning);
firstpublisher.first('hha');
firstpublisher.second('hahmonth','night');
firstpublisher.dissubcribe(Rose.night, 'night');
firstpublisher.dissubcribe(Rose.morning);
console.log('^&^&^&^^');
firstpublisher.first('hha');
firstpublisher.second('hahmonth','night');
结果显示:
看了网上有用函数实现的,先mark下:
function Publisher(subscribers){
this.subscribers = subscribers || {'any': []};
Publisher.prototype.subscribe = function(fn, type){
var type = type || 'any';
if(typeof this.subscribers[type] === 'undefined'){
this.subscribers[type] = [];
}
this.subscribers[type].push(fn);
};
Publisher.prototype.unsubscribe = function(fn, type){
var type = type || 'any';
for(var i=0, len = this.subscribers[type].length; i<len; i++){
if(this.subscribers[type][i] === fn){
this.subscribers[type].splice(i,1);
}
}
};
Publisher.prototype.publish = function(publication, type){
var type = type || 'any';
for(var i=0, len = this.subscribers[type].length; i<len; i++){
this.subscribers[type][i](publication);
}
};
}
var paper = new Publisher();
paper.daily = function(){
this.publish(' this is Olympic ! ');
};
paper.monthly = function(){
this.publish(' last month is the 28th Olympic! ', 'monthly');
};
var Jack = {
readInMorning: function(news){
console.log('Jack reads ' + news + ' in the morning');
},
readInSunday: function(news){
console.log('Jack reads ' + news + ' on Sunday');
}
};
var Amy = {
readInMorning: function(news){
console.log('Amy reads ' + news + ' in the morning');
},
readInSunday: function(news){
console.log('Amy reads ' + news + ' on Sunday');
}
};
paper.subscribe(Jack.readInMorning);
paper.subscribe(Jack.readInSunday, 'monthly');
paper.subscribe(Amy.readInMorning);
paper.subscribe(Amy.readInSunday, 'monthly');
paper.daily(); //Jack reads this is Olympic ! in the morning
//Amy reads this is Olympic ! in the morning
paper.monthly(); //Jack reads last month is the 28th Olympic! on Sunday
//Amy reads last month is the 28th Olympic! on Sunday
paper.unsubscribe(Jack.readInSunday,'monthly');
paper.daily(); //Jack reads this is Olympic ! in the morning
//Amy reads this is Olympic ! in the morning
paper.monthly(); //Amy reads last month is the 28th Olympic! on Sunday
好了,观察模式就写这些了,后续接着再补充吧~~~