zoukankan      html  css  js  c++  java
  • 设计模式之发布-订阅模式

    发布-订阅模式

    发布-订阅模式与观察者模式是一个相似的模式,功能上是差不多的。

    但观察者模式更合适面向对象的写法,所以在js里看情况使用,如果

    不太习惯使用js的面向对象,那么发布-订阅模式就够了。

    发布-订阅模式在现今使用的很多,在各大框架,插件都被使用,因为的

    它的解耦合,可以大大的提高代码的复用性,比如现在的MVVM框架都有

    使用它,或者模块化通信都有使用,如果拜读过jQuery源码的都应该看到

    这个模式运用,只是或者你不太甚了解它,为什么它被运用的那么频繁了?

    因为代码之间的高度解耦合,现在的都是追求代码复用性高,高质量代码的年代,

    所以这个模式很适合,但它也有很大的bug,就是代码追踪可能给你增加难度,

    这是很正常的,代码之间的关联关系已经不强,那么他们之间追踪起来就会难。

    它运用例子场合,如房东与租客,现在的房东大多数都是通过中介把消息推送出去给租客,

    所以租客只要和中介有关联就可以知道哪里有房子租。因为中介会租客推送房子的消息。

    又或者如微信的关注了公众号,当你微信关闭时是没有收到公众号发布的消息的,但当你上线后

    之前离线的发布的消息就会全部推送给你,因为你关注的它,这是个订阅的过程,和发布的过程。

    所以可以先订阅再发布,也可以先发布再订阅。

    /*发布-订阅模式*/
    
        var Event=(function(){
            var event,
                //默认命名空间名
                _default="default";
                event=function(){
                    //内部的方法
                    var _create,_listen,_trigger,_remove;
                    //数组的操作
                    var _shift=Array.prototype.shift,
                        _unshift=Array.prototype.unshift;
                    //缓存空间
                    var cacheSpacename={};
                    //循环调用
                    var each=function(ary,fn){
                        //判断是否有方法被调用,使用来判断是否离线
                        var ret=false;
                        for(var i=0,l=ary.length;i<l;i++){
                            var n=ary[i];
                            //调用方法,改变this
                            ret=fn.call(n,i,n);
                        }
                        return ret;
                    } 
                    _listen=function(key,fn,cache){
                        if(!cache[key]){
                            cache[key]=[];
                        }
                        cache[key].push(fn);
                    }
                    _trigger=function(){
                        var cache=_shift.call(arguments);
                        var key=_shift.call(arguments);
                        var args=arguments;
                        var _self=this;
                        if(!cache[key]){
                            return false;
                        }
                        var ret=each(cache[key],function(){
                            //因为this改变,所以这里的this缓存里的函数
                            this.apply(_self,args);
                        });
                        return ret;
                    }
                    _remove=function(key,fn,cache){
                        if(!cache[key]||!fn){
                            cache[key]=[];
                            return false;
                        }
                        for(var i=0;i<cache[key].length;i++){
                            if(cache[key][i]==fn){
                                cache[key].splice(i,1);
                                i--;
                            }
                        }
                        return true;
                    }
                    _create=function(namespace){                    
                            var cache,ret,offlineCache;
                            if(!namespace){
                                namespace=_default;
                            }
                            //缓存空间,重点,使用来存缓存数据和离线数据
                            cache=cacheSpacename[namespace]?cacheSpacename[namespace]:cacheSpacename[namespace]={};
                            offlineCache=cache["offlineCache"]?cache["offlineCache"]:cache["offlineCache"]={};
                            ret={
                                listen:function(key,fn){
                                    _listen(key,fn,cache);
                                    //判断离线缓存是否存在
                                    if(!offlineCache[key]||offlineCache[key].length==0){
                                        return false;
                                    }
                                    _unshift.call(arguments,offlineCache);
                                    _trigger.apply(this,arguments);
                                    //离线缓存只是用一次
                                    delete offlineCache[arguments[1]];
                                },
                                trigger:function(){
                                    var args,
                                    _self=this;
                                    _unshift.call(arguments,cache);
                                    args=arguments;
                                    var e=_trigger.apply(_self,args);
                                    if(e){
                                        return false;
                                    }
                                    //使用闭包的访问到离线前的数据参数
                                    var fn=function(){
                                        _trigger.apply(_self,args);
                                    }
                                    //离线缓存
                                    if(!offlineCache[args[1]]){
                                        offlineCache[args[1]]=[];
                                    }
                                    offlineCache[args[1]].push(fn);
                                },
                                remove:function(key,fn){
                                    _remove(key,fn,cache);
                                }    
                            };
                            return ret;
                    }
                    return {
                        create:_create,
                        listen:function(key,fn){
                            var event=this.create();
                                event.listen(key,fn);
                        },
                        trigger:function(){
                            var event=this.create();
                                event.trigger.apply(this,arguments);
                        },
                        remove:function(key,fn){
                            var event=this.create();
                                event.remove(key,fn);
                        }
                    }
                }
                return event();
        })();
    
        /*测试*/
        function a(a){
            console.log(a);
        }
        function b(a){
            console.log("b:"+a);
        }
        Event.trigger("c","default");
        Event.listen("c",a);
        Event.create("zhang").trigger("c","abc");
        Event.create("zhang").listen("c",a);
        Event.create("zhang").trigger("c","abcaa");
        Event.create("zhang").trigger("c","abcxxx");
        Event.create("zhanga").trigger("c","abc");
        Event.create("zhanga").listen("c",a);
        Event.create("zhanga").listen("c",b);
        Event.create("zhanga").remove("c",a);
        Event.create("zhanga").trigger("c","abcxxss");
  • 相关阅读:
    20145201 《Java程序设计》第一周学习总结
    调查问卷
    Hello Java
    Java学习——开端
    java,我准备好了
    20145229吴姗珊 《Java程序设计》第4周学习总结
    20145229吴姗珊 《Java程序设计》第3周学习总结
    20145229吴姗珊《Java程序设计》第二周学习总结
    20145229吴姗珊《JAVA程序设计》第一周学习总结
    20145207 《信息安全系统设计基础》期中总结
  • 原文地址:https://www.cnblogs.com/zhangzhicheng/p/7029639.html
Copyright © 2011-2022 走看看