策略模式学习笔记

平时咱们在写代码时会偶尔用到策略模式的思想,但咱们却不自知。今天学习了策略模式,特记录以下:html

策略模式的定义是:定义一系列的算法,把他们一个个封装起来,而且使它们能够相互替换。算法

策略模式的目的是:将算法的使用和实现分离开来。一个基于策略模式的程序至少由两部分组成。第一部分是一组策略类,策略类封装了具体的算法,并负责具体的计算过程。第二部分是环境类Context,Context接受客户的请求,随后把请求委托给某一个策略类,Context要维持对某个策略对象的引用。app

在开发项目时,确定离不开表单检验这一个环节。dom

在编写一个注册页面时,在点击注册按钮以前,须要作几条校验逻辑:post

1.用户名不能为空;学习

2.密码长度不能少于6位;this

3.手机号码必须符合格式。spa

如今开始用策略模式实现:prototype

第一步:把校验逻辑封装成策略对象插件

var strategies={
    isNotEmtpy:function(value, errorMsg){
        if(value==''){
            return errorMsg;
        }
    },
    minLenth:function(value, length, errorMsg){
        if(value.length < length){
            return errorMsg;
        }
    },
    isMobile:function(value, errorMsg){
        if(!/(^1[3|5|8][0-9]{9}$)/.test(value)){
            return errorMsg;
        }
    }
}

第二步:准备实现Validator类,Validator类这里做为Context,负责接收用户的请求并委托给策略对象。

var Validator = function(){
    this.cache = [];  //保存校验规则
}
Validator.prototype.add=function(dom, rules){
    var _this=this;
    for(var i=0,rule;rule = rules[i++];){
        (function(rule){
            var strategyAry = rule.strategy.split(':');
            var errorMsg = rule.errorMsg;
            _this.cache.push(function(){
                var strategyName = strategyAry.shift();
                strategyAry.unshift(dom.value);
                strategyAry.push(errorMsg);
                return strategies[strategyName].apply(dom, strategyAry);
            })
        })(rule);
    }
}
Validator.prototype.start=function(){
    console.log(this.cache)
    for( var i=0, validatorFunc; validatorFunc = this.cache[i++]; ){
        var msg = validatorFunc();
        if(msg){
            return msg;
        }
    }
}

有了上面的策略对象和环境类,剩下的就是调用了。一下附上完整代码。

<!DOCTYPE html>
<html>
<head>
	<title>dmeo</title>
</head>
<body>
	<form id="registerForm" method="post">
		请输入用户名:<input type="text" name="username" />
		请输入密码:<input type="text" name="userpwd" />
		<button>提交</button>
	</form>
<script>
	/***************** 策略部分 ******************/
	var strategies={
		isNotEmtpy:function(value, errorMsg){
			if(value==''){
				return errorMsg;
			}
		},
		minLenth:function(value, length, errorMsg){
			if(value.length < length){
				return errorMsg;
			}
		},
		isMobile:function(value, errorMsg){
			if(!/(^1[3|5|8][0-9]{9}$)/.test(value)){
				return errorMsg;
			}
		}
	}

	/***************** 环境Context部分 ******************/
	var Validator = function(){
		this.cache = [];  //保存校验规则
	}
	Validator.prototype.add=function(dom, rules){
		var _this=this;
		for(var i=0,rule;rule = rules[i++];){
			(function(rule){
				var strategyAry = rule.strategy.split(':');
				var errorMsg = rule.errorMsg;
				_this.cache.push(function(){
					var strategyName = strategyAry.shift();
					strategyAry.unshift(dom.value);
					strategyAry.push(errorMsg);
					return strategies[strategyName].apply(dom, strategyAry);
				})
			})(rule);
		}
	}

	Validator.prototype.start=function(){
		console.log(this.cache)
		for( var i=0, validatorFunc; validatorFunc = this.cache[i++]; ){
			var msg = validatorFunc();
			if(msg){
				return msg;
			}
		}
	}

	/***************** 调用部分 ******************/
	var validatorFn = function(){
		var validator = new Validator();
		validator.add(registerForm.username, [{strategy:'isNotEmtpy',errorMsg:'用户名不能为空!'},{strategy:'minLenth:4',errorMsg:'用户名长度不能少于4位!'}] );
		validator.add(registerForm.userpwd, [{strategy:'minLenth:6',errorMsg:'密码长度不能少于6位!'}]);
		var errorMsg = validator.start();
		return errorMsg;
	}

	var registerForm = document.getElementById('registerForm');
	registerForm.onsubmit = function(){
		var errorMsg = validatorFn();
		if(errorMsg){
			alert(errorMsg);
			return false;
		}
	}
</script>
</body>
</html>

还能够作成一个适合项目的校验插件,方便调用。

策略模式还能够有其余使用场景:能够用来封装一系列的"业务规则",单出现不少判断条件语句时,就能够思考一下是否能够使用策略模式。

若有错误,请指正!

相关文章
相关标签/搜索