首页 > 代码库 > JS设计模式——策略模式

JS设计模式——策略模式

核心:定义一些列的算法(逻辑)封装起来,并且它们是平等关系可以相互替换
js中的策略模式关键字:策略和业务分离

(一)基本实现

常见代码:

function playGame(gameName){	let str;	if(gameName == ‘footBall‘){		str = ‘不喜欢玩足球‘	}else if(method == ‘basketball‘){		str = ‘不喜欢玩蓝球‘	}else if(method == ‘pingpang‘){		str = ‘不喜欢玩乒乓‘	}else if(method == ‘swing‘){		str = ‘好啊,我最喜欢游泳了‘	}	alert(str)}

策略模式优化

let gameStrategies = {	‘footBall‘: function(){		return ‘不喜欢玩足球‘	},	‘basketball‘: function(){		return ‘不喜欢玩蓝球‘	},	‘pingpang‘: function(){		return ‘不喜欢玩乒乓‘	},	‘swing‘: function(){		return ‘好啊,我最喜欢游泳了‘	}}function playGame_1(gameName){	let str;	str = gameStrategies(gameName)	alert(str)}

  将策略单独提取出来封装,和业务代码分离。这样需要修改策略不需要去业务代码里面查找,而提取出来的策略也可以被多个业务代码复用。

(二)场景案例

//策略模式实现表单判断let formStrategies = {	isNonEmpty: function(val,errorMsg){		if(val == ‘‘){			return errorMsg		}	},	minLength: function(val,length,errorMsg){		if(val.length < length){			return errorMsg		}	},	isMobile: function(val,errorMsg){		if(!/(^1[3|5|8][0-9]{9}$)/.test(val)){			return errorMsg		}	}}registerForm.onsubmit = function(){	let userNameErrorMsg = formStrategies.isNonEmpty(registerForm.userName,‘用户名不能为空‘)	let pwdErrorMsg = formStrategies.minLength(registerForm.pwd,‘密码长度不能少于6位‘)	let telErrorMsg = formStrategies.isMobile(registerForm.tel,‘手机格式不正确‘)	if(userNameErrorMsg){		alert(userNameErrorMsg)	}else if(pwdErrorMsg){		alert(pwdErrorMsg)	}else if(telErrorMsg){		alert(telErrorMsg)	}}

  这里可以继续优化

//start--------实现一个可配置策略的验证类function Validator(){	this.rules = []	//待验证规则队列}Validator.prototype.add = function(rule,dom,errorMsg){	let _rule = rule.split(‘:‘) //把策略和参数分开,比如minLength:6	this.rules.push(function(){		let strategy = _rule.shift() //策略字符串		_rule.unshift(dom.value)		_rule.push(errorMsg)		return formStrategies[strategy].apply(dom,_rule)	})}Validator.prototype.start = function(){	for(let i = 0,validatorFunc;validatorFunc = this.rules[i++];){		let msg = validatorFunc()		if(msg)return msg	}}//end-----------let validataFunc = function(){	let validator = new Validator()	validator.add(registerForm.userName,‘isNonEmpty‘,‘用户名不能为空‘)	validator.add(registerForm.pwd,‘minLength‘,‘密码长度不能少于6位‘)	validator.add(registerForm.tel,‘isMobile‘,‘手机格式不正确‘)	let errorMsg = validator.start()	return errorMsg}registerForm.onsubmit = function(){	let errorMsg = validataFunc()	if(errorMsg){		alert(errorMsg)		return	}}

(三)场景案例

//上午返回‘上午好‘;中午返回‘中午‘;下午返回‘下午好‘;晚上返回‘晚上好‘;凌晨返回‘凌晨了,请马上休息‘function say(){	var hour = new Date().getHours()	if(hour > 6 && hour < 12){		return ‘上午好‘	}else if(hour >= 12 && hour <= 13){		return ‘中午好‘	}else if(hour > 13 && hour <18){		return ‘下午好‘	}else if(hour >= 18 && hour < 24){		return ‘晚上好‘	}else{		return ‘凌晨了,请马上休息‘	}}//策略模式//语言策略var say_words = {	morning : function(){		return ‘上午好‘	},	noon : function(){		return ‘中午好‘	},	afternoon : function(){		return ‘下午好‘	},	night : function(){		return ‘晚上好‘	},	beforeDawn : function(){		return ‘凌晨了,请马上休息‘	}}//时间策略var say_times = {	time6_12 : function(hour){		return hour > 6 && hour < 12	},	time12_13 : function(hour){			return hour >= 12 && hour <= 13	},	time13_18 : function(hour){		return hour > 13 && hour <18	},	time18_24 : function(hour){		return hour >= 18 && hour < 24	},	time0_6 : function(hour){		return hour >= 0 && hour <= 6	},}function say1(){	var hour = new Date().getHours()				if(say_times.time6_12){		return say_words.morning()	}else if(say_times.time12_13){		return say_words.noon()	}else if(say_times.time13_18){		return say_words.afternoon()	}else if(say_times.time18_24){		return say_words.night()	}else{		return say_words.beforeDawn()	}}//继续优化function say2(){	var hour = new Date().getHours()			//策略模式和多态思想结合	function doSayByStrategies(arr){		for(var i in arr){								if(say_times[i](hour)){				return arr[i]()					}		}	}	return doSayByStrategies({				time6_12:say_words.morning,				time12_13:say_words.noon,				time18_24:say_words.night			})	}

  这个例子其实并不是一个好例子,因为使用策略模式显得比直接使用if else语句更加繁琐,这个例子中如果say_words和say_times的逻辑比较复杂且需要很多场景共用,则该模式的好处将愈发显现。

 

JS设计模式——策略模式