• 设计模式


    一、单例模式

     1 /**
     2  *  执行当前 Single 值获得唯一一个对象
     3  */
     4 var Single = (function(){
     5     var instance;
     6     function init(){
     7         return {
     8 
     9         };    
    10     }
    11 
    12     return {
    13         //获取实例
    14         getInstance: function(){
    15             if(!instance){
    16                 instance = init();
    17             }
    18             return instance;
    19         }
    20     }
    21 })();
    22 
    23 var obj1 = Single.getInstance();
    24 var obj2 = SIngle.getInstance();
    25 
    26 console.log(obj1 === obj2);

    或者

     1 //管理单例的逻辑代码,如果没有数据则创建,有数据则返回
     2 var getSIngle = function(fn){    //参数为创建对象的方法
     3     var result;
     4     return function(){    //判断是Null或赋值
     5         return resule || (result = fn.apply(this,argument));
     6     };
     7 };
     8 
     9 //创建登陆窗口方法
    10 var createLoginLayer = function(){
    11     var div = document.createElement('div');
    12     div.innerHTML = '我是登陆浮窗';
    13     div.style.display = 'none';
    14     document.body.appendChild(div);
    15     return div;
    16 }
    17 
    18 //单例方法
    19 var createSingleLoginLayer = getSingle(createLoginLayer);
    20 
    21 //使用惰性单例,进行创建
    22 document.getElementById('loginBtn').onclick = function(){
    23     var loginLayer = createSingleLoginLayer();
    24     loginLayer.style.display = 'block';
    25 };

    二、观察者模式

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

      例如事件绑定,就是一个标准的观察者模式。

    document.body.addEventListener('click',function(){
        console.log(2);
    },false);
    document.body.click();

      实例,售楼处可以接受买房登记,登记后的用户如果有房源,则会逐一告知。并且可以进行取消登记操作。

      为了彻底结束耦合性,可以使用全局变量制作监听事件。

    var ObserverEvent (function(){
        var clientList = [], listen, trigger, remove;
        listen = function(key, fn){
            if(!clientList[key]){
                clientList[key] = [];
            }
            clientList[key].push(fn);
        };
        trigger = function(){
            var Array.prototype.shift.call(arguments), fns = 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);
            }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
        }
    })();
    
    ObserverEvent.listen('squareMeter88', fn1 = function(price){
        console.log('价格=' + price);
    });
    ObserverEvent.listen('squareMeter100',function(price){
        console.log('价格=' + price);
    });
    ObserverEvent.trigger('squareMeter88',200000);
    ObserverEvent.trigger('squareMeter100',300000);
    ObserverEvent.remove('squareMeter88',fn1);
    ObserverEvent.trigger('squareMeter88',200000);

      当然这种售楼处只是一个例子,在现实中,登陆页面后,会需要刷新各个模块的信息(头像、nav)这类。我们也可以使用观察者模式进行刷新操作。

      我们直接改用调用方法即可,而且是完全的解耦合。

    var header = (function(){
        ObserverEvent.listen('loginSucc',function(data){
            header.setAvatar(data.avatar);
        });
        return{
            setAvatar:function(data){
                console.log(data + "设置header成功");
            }
        }
    })();
    var nav = (function(){
        ObserverEvent.listen('loginSucc',function(data){
            nav.setAvatar(data.avatar);
        });
        return {
            setAvatar: function(data){
                console.log(data + "设置nav成功");
            }
        }
    })();
    var data = {};
    data.avatar = "参数";
    ObserverEvent.trigger("loginSucc",data);

    观察者模式的优点很明显:时间上的解耦,对象之间的解耦。

    三、职责链模式

      使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系。将对象形成一条链,并沿着这条链传递请求。

      使用orderType和pay来控制流向。分别进行不同对象的流转。

    职责链模式1:

    var order500 = function(orderType, pay, stock){
        if(orderType === 1 && pay === true){
            console.log("500元定金");
        }else{
            order200(orderType, pay, stock);
        }
    };
    
    var order200 = function(orderType, pay, stock){
        if(orderType === 2 && pay === true){
            console.log("200元定金");
        }else{
            orderNormal(orderType, pay, stock);
        }
    };
    
    var orderNormal = function(orderType, pay, stock){
        if(stock > 0){
            console.log("普通购买");
        }else{
            console.log("手机库存不足");
        }
    };
    
    order500(1,true,500);

    但是这种职责链体系,耦合度比较高,例如500对象与200对象,耦合度很高。

    职责链模式2:

    var order500 = function(orderType, pay, stock){
        if(orderType === 1 && pay === true){
            console.log("500元定金");
        }else{
            return "nextSuccessor";
        }
    };
    
    var order200 = function(orderType, pay, stock){
        if(orderType === 2 && pay === true){
            console.log("200元定金");
        }else{
            reutrn "nextSuccessor";
        }
    };
    
    var orderNormal = function(orderType, pay, stock){
        if(stock > 0){
            console.log("普通购买");
        }else{
            console.log("手机库存不足");
        }
    };
    
    var Chain = function(fn){
        this.fn = fn;
        this.success = null;
    };
    Chain.prototype.setNextSuccessor = function(successor){
        return this.success = successor;
    };
    Chain.prototype.passRequest = function(){
        var ret = this.fn.apply(this, arguments);
        if(ret === "nextSuccessor"){
            return this.success && this.success.passRequest.apply(this.success, arguments);
        }
    };
    
    var chainOrder500 = new Chain(order500);
    var chainOrder200 = new Chain(order200);
    chainOrder500.setNextSuccessor(chainOrder200);
    chainOrder500.passRequest(2, true, 200);

    四、装饰者模式

      装饰者模式可以动态的给某个对象添加一些额外的职责,而不会影响从这个类派生的其他对象。

    var plance = {
        fire : function(){
            console.log("发射普通子弹");
        }
    };
    
    var missileDecorator = function(){
        console.log("发射导弹");
    };
    
    var fire1 = plance.fire;
    plance.fire = function(){
        fire1();
        missileDecorator();
    };
    plance.fire();

    或者使用装饰函数(AOP)Function的after或者before

    var plance = function() {  };
    plance.prototype.fire = function(){
        console.log("发射普通子弹");
    };
    
    var missileDecorator = function(){
        console.log("发射导弹");
    };
    
    Function.prototype.after = function(afterfn){
        var _self = this;
        return function(){
            var ret = _self.apply(this, arguments);
            afterfn.apply(this, arguments);
            return ret;
        };
    };
    
    var pl = new plance();
    pl.fire = pl.fire.after(missileDecorator);
    pl.fire();

    装饰函数是一个很实用的功能,例如我们制作插件式的表单验证,就可以使用装饰函数。

    var registerForm = document.getElementById("registerForm");
    Function.prototype.before = function(beforeFn){
        var _self = this;
        return function(){
            if(beforeFn.apply(this,arguments) === false){
                return;
            }
            return _self.apply(this,arguments);
        };
    }
    
    var validata = function(){
        if(registerForm.userName.value === ""){
            alert("用户名不能为空");
            return false;
        }
    };
    
    var formSubmit = function(){
        console.log("成功");
    }
    formSubmit = formSubmit.before(validata);
    registerForm.onsubmit = function(){
        formSubmit();
        return false;
    };
  • 相关阅读:
    最优贸易 NOIP 2009 提高组 第三题
    Think twice, code once.
    luogu P1378 油滴扩展
    codevs 1002 搭桥
    codevs 1014 装箱问题 2001年NOIP全国联赛普及组
    洛谷P2782 友好城市
    洛谷P1113 杂务
    [HDU1848]Fibonacci again and again
    [POJ2420]A Star not a Tree?
    [SCOI2010]生成字符串
  • 原文地址:https://www.cnblogs.com/haishen/p/9788146.html
Copyright © 2020-2023  润新知