设计模式之单例模式与策略模式

单例模式

简单就是只会执行一次的函数

//代理模式下 的 单例制造函数

var c = 1;
function letSingle () { //代理函数
  var fn = [].shift.call(arguments,1); // 获得传入的函数
  var instance; //通过闭包保存的实例,初始为undefined
  var _arguments = arguments;
  return function () { // 返回函数,形成闭包
		if(!instance) { //通过instance判断是否执行
			instance=fn.call(this,_arguments); 执行fn并且保存返回值
		}
	return instance;
  }
}

var b=letSingle(function(){
  console.info("b执行");
  return (c++);
});
//此时 b为letSingle所返回的函数;

console.info(b());
console.info(b());
console.info(b());	

输出为 : 
b执行
1
1
1

单例模式和惰性加载是非常类似的,都是通过闭包保存一个判断的变量,
不同在于,单例是判断是否返回值,每次调用,都需要判断
惰性是判断返回的函数是哪一个,只在第一次判断

策略模式

用组合,代理,多态等,将一组算法或者业务逻辑封装成一个策略类

//验证类
var validate = {
	errorMsg:[],
	strateg:{},
	addRule:function(data){
		var type;
		var name = data.name;
		// data.strateg 当data.strateg为string时,转换为数组;
		// data.name 为空则推入错误,返回this
		if(!Array.isArray(data.strateg)) data.strateg = [data.strateg];
		if(!data.name){
			this.errorMsg.push("addRule中,name不能为空"); 
			return this;
		};
		for( i in data.strateg){
			type = data.strateg[i];
			if(this.strateg[type]){
				//如果存在此规则 --- 执行验证函数
				var info = this.strateg[type](data.name,data.value,data.info);				
				if(!info) continue;
				this.errorInfo(info,data.info.errorMsg);
			}else{
				//出现不存在的验证规则,则推入一个错误
				this.errorMsg.push("不存在此验证规则:"+type);
			}
		}
		return this;				
	},
	outputError:function(){
		if(this.errorMsg.length==0) return false;	
		return this.errorMsg.join("\n");
	},
	errorInfo:function(info,customInfo){
		customInfo ? this.errorMsg.push(customInfo) : info && this.errorMsg.push(info);	
	}
}


//策略类--验证规则	
validate.strateg.isEmpty = function(name,value){
	var prompt = false;
	if(value === '' || value === undefined){
		prompt = name+"的值不能为空";
	};
	return prompt;
};
validate.strateg.isAlphaNum = function(name,value){
	var prompt = false;
	if(/[^a-z0-9]/i.test(value)){
		prompt = name+"传入的值只能是字母和数字不能包含特殊字符";
	};
	return prompt;
};
validate.strateg.isNumber = function(name,value,info){
	var prompt = false;
	var minLength = info.minLength || 6;	
	if( isNaN(value) || value.toString().length<minLength){
		var prompt = name+"只能是数字且不小于"+minLength+"位";
	};
	return prompt;
};

// 用户代码
	var data1 = "***",
		data2 = '',
		number = 123,
		string = "STRING";
		
var errors = validate
	.addRule({
		name:'data1',
		value:data1,
		strateg:["isEmpty","isAlphaNum"],
		info:{
			
		}	
	})
	.addRule({
		name:'number',
		value:number,
		strateg:["isEmpty","isNumber"],
		info:{
			minLength:6
		}	
	})
	.addRule({
		name:'string',
		value:string,
		strateg:["isEmpty","isArr","isNumber"],
		info:{
			minLength:9
		}	
	})
	.addRule({
		name:'data2',
		value:data2,
		strateg:"isEmpty",
		info:{
			minLength:6
		}	
	})
	.addRule({
		value:string,
		strateg:"isEmpty",
		info:{
			minLength:6
		}	
	})
	.outputError();
	console.error(errors);

    输出为
data1传入的值只能是字母和数字不能包含特殊字符
number只能是数字且不小于6位
不存在此验证规则:isArr
string只能是数字且不小于9位
data2的值不能为空
addRule中,name不能为空

总体就是将验证规则组成一个策略组,然后validate对象将验证交给这个组代理

posted @ 2017-02-18 19:36  ABC君  阅读(403)  评论(0编辑  收藏  举报