设计模式

一、单例模式

 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;
};
原文地址:https://www.cnblogs.com/haishen/p/9788146.html