《JavaScript设计模式与开发实践》读书笔记之观察者模式

1.观察者模式

观察者模式定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知。

JavaScript中通常采用事件模型替代传统的观察者模式

1.1 逐步实现观察者模式

以客户看房为例

首先指定谁充当发布者,如售楼处

然后给发布者添加一个缓存列表,用于存放回调函数以便通知订阅者。这里为了让订阅者只接收自己感兴趣的消息,增加一个标识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('squareMeter88',function(price){//A订阅88平房子消息
    console.log('价格='+price);
});

salesOffices.listen('squareMeter100',function(price)){//B订阅100平房子消息
    console.log('价格='+price);
}

salesOffices.trigger('squareMeter88',200000);
salesOffices.trigger('squareMeter100',300000);

1.2 观察者模式通用实现

var Event=(function(){
    var clientList={},
        listen,
        trigger,
        remove;
    listen=function(key,fn){
        f(!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(key,fn){
        var fns=clientList[key];
        if(!fns){
            return false;
        }
        if(!fn){
            fns&&(fns.length=0);//没指定fn时,删除全部
        }else{
            for(var l=fns.length-1;l>=0;l--){
                var _fn=fns[l];
                if(_fn === fn){
                    fns.splice(l,1);
                }
            }
        }
    };
    return{
        listen:listen,
        trigger:trigger,
        remove:remove
    }
})();

Event.listen('squareMeter88',function(price){//A订阅88平房子消息
    console.log('价格='+price);
});

Event.trigger('squareMeter88',200000);

 

posted @ 2015-07-16 22:47  GongQi  阅读(422)  评论(0编辑  收藏  举报