javascript 设计模式之发布-订阅模式(观察者模式)
发布-订阅模式也叫观察者模式,它定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知.在 javascript 开发中,我们一般用事件模型来替代传统的发布-订阅模式.
我们接下来实现一个简单的发布订阅模式,模拟售楼处可以给订阅者发送房屋消息,在这里售楼处作为发布者,小明与小红作为订阅者
var salesOffices = {};//定义售楼处 salesOffices.clientList = [];//缓存列表 salesOffices.listen = function(fn){//增加订阅者 this.clientList.push(fn);//订阅的消息添加进缓存列表 } salesOffices.trigger = function(){//发布消息 for(var i =0,fn;fn=this.clientList[i];i++){ fn.apply(this,arguments); //arguments 是发布消息时带上的参数 } } salesOffices.listen(function(price,squareMeter){//小明订阅消息 console.log('价格='+price); console.log('平米='+squareMeter); }); salesOffices.listen(function(price,squareMeter){//小红订阅消息 console.log('价格='+price); console.log('平米='+squareMeter); }); salesOffices.trigger(2000000,88);//输出 2 个价格=2000000,平米=88
至此我们完成了一个简单的发布-订阅模式,但是还存在一个问题,订阅者接收到了发布者发布的每个消息,所以有必要增加一个标示 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];i++){ fn.apply(this,arguments); } } salesOffices.listen("平米 88",function(price){//小明订阅的是 88 平米房屋的消息 console.log('88 平米房子价格='+price); }); salesOffices.listen("平米 120",function(price){//小红订阅的是 88 平米房屋的消息 console.log('120 平米房子价格='+price); }); salesOffices.trigger("平米 88",2000000);//发布 88 平米房屋的价格消息 salesOffices.trigger("平米 120",3000000);//发布 120 平米房屋的价格消息
现在订阅者就可以订阅自己感兴趣的事件了!
