一、单例模式
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; };