JavaScript设计模式行为型设计模式--发布-订阅模式

Posted Wendy-lxq

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaScript设计模式行为型设计模式--发布-订阅模式相关的知识,希望对你有一定的参考价值。

       发布-订阅者模式又叫观察者模式,它定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知。那具体的含义,就是有订阅者和发布者,两者的功能,订阅是请求在某些事件(event)到达时可以通知它并执行对应的动作(action),而发布则相对的是向订阅告知事件(event)已经到达,你可以执行对应的动作(action)了。

      举一个现实中的例子。我们在现实中可以看到一个现象:假如A要去买房子,那么这个A就会把自己的联系方式给售楼处的负责人,只要楼盘有房子就会通知A,然后A就可以过去看房子,买房子,就不需要每天都去打电话询问是不是到了购买时间,这个例子就可以利用发布-订阅者模式进行实现,这个售楼处负责人是发布者,A是订阅者,接下来我们实现简单的发布-订阅者模式。

代码如下:

var salesOffices = ;//定义售楼处
salesOffices.clientList = [];//缓存列表,存放订阅者的回调函数
//增加订阅者
salesOffices.listen = function ( fn )
	this.clientList.push( fn );  //订阅的消息存进缓存列表
;
//发布消息
salesOffices.trigger = function ()
	for(var i = 0, fn; fn = this.clientList[ i++ ];)
		fn.apply(this,arguments);
	
;
//A订阅消息
salesOffices.listen( function(price, squareMeter)
	console.log('价格=' + price);
	console.log('squareMeter=' + squareMeter);
);
//B订阅消息
salesOffices.listen( function(price, squareMeter)
	console.log('价格=' + price);
	console.log('squareMeter=' + squareMeter);
);

salesOffices.trigger(20000,88);//价格=20000  squareMeter=88
salesOffices.trigger(30000,110); //价格=30000  squareMeter=110
     以上代码实现了最简单的发布-订阅模式,但是这里还存在一些问题。我们看到订阅者接收到了发布者发布的每个消息,虽然A只想买88平方米的房子,但是发布者把110平方米的信息也发给了A,这对于小明来说是不必要的,所以我们需要增加一个标识key,让订阅者只订阅自己感兴趣的消息。修改之后的代码如下:

var salesOffices = ;//定义售楼处
salesOffices.clientList = [];//缓存列表,存放订阅者的回调函数
//增加订阅者
salesOffices.listen = function ( key, fn )
	if( !this.clientList[ key] )
		this.clientList[ key ] = [];  //如果还没有订阅过此类消息,给该类消息创建一个缓存列表
	
	this.clientList[ key ].push( fn ); //订阅的消息存进缓存列表
;
//发布消息
salesOffices.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);
	
;

salesOffices.listen('squareMeter80', function(price)
	console.log('价格=' + price);
);

salesOffices.listen('squareMeter100', function(price)
	console.log('价格=' + price);
);

salesOffices.trigger('squareMeter80',20000);  //发布88平方米房子的价格
salesOffices.trigger('squareMeter100',30000); //发布110平方米房子的价格
     接下来实现一个通用的发布-订阅模式。
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()
		var fns = this.clientList[ key ];

		if( !fns)
			return false;
		
		if( !fn)
			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 = ;
var fn1,fn2;
installEvent(salesOffices);
//A订阅消息
salesOffices.listen('squareMeter88', fn1 = function( price )
	console.log('价格=' + price);
);
//B订阅消息
salesOffices.listen('squareMeter88', fn2 = function( price )
	console.log('价格=' + price);
);

salesOffices.remove('squareMeter88', fn1 );//删除A的订阅
salesOffices.trigger('squareMeter88', 20000 );//价格=20000




以上是关于JavaScript设计模式行为型设计模式--发布-订阅模式的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript设计模式行为型设计模式--策略模式

JavaScript设计模式行为型设计模式--模板方法模式

JavaScript设计模式行为型设计模式--职责链模式

Javascript设计模式

JAVA SCRIPT设计模式--行为型--设计模式之Strategy策略模式(21)

JAVA SCRIPT设计模式--行为型--设计模式之Command命令模式(14)