JavaScript策略模式

<html>

<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>

<body>
	<form action="http:// xxx.com/register" id="registerForm" method="post">
		请输入用户名:<input type="text" name="userName"/ >
		请输入密码:<input type="text" name="password"/ >
		请输入手机号码:<input type="text" name="phoneNumber"/ >
		<button>提交</button>
	</form>
	<script>
		/***********************策略对象**************************/
		var strategies = {
			isNonEmpty: function( value, errorMsg ){
				if ( value === '' ){
					return errorMsg;
				}
			},
			minLength: 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 类**************************/
		var Validator = function(){
			this.cache = [];     // 保存校验规则  
		};
		Validator.prototype.add = function( dom, rules ){
			var self = this;     //当在window对象中执行该函数的时候,this指向被改变,用self来保存在闭包中。
			for ( var i = 0, rule; rule = rules[ i++ ]; ){
				(function( rule ){
					var strategyAry = rule.strategy.split( ':' ); // 把strategy 和参数分开
					var errorMsg = rule.errorMsg;
					self.cache.push(function(){   // 把校验的步骤用空函数包装起来,并且放入cache
						var strategy = strategyAry.shift();   // 用户挑选的strategy
						strategyAry.unshift( dom.value );   // 把input 的value 添加进参数列表
						strategyAry.push( errorMsg );   // 把errorMsg 添加进参数列表
						return strategies[ strategy ].apply( dom, strategyAry );
					});
				})( rule )
			}
		};
		Validator.prototype.start = function(){
			for ( var i = 0, validatorFunc; validatorFunc = this.cache[ i++ ]; ){
				var errorMsg = validatorFunc();
				if ( errorMsg ){
					return errorMsg;
				}
			}
		};
		/***********************客户调用代码**************************/
		var registerForm = document.getElementById( 'registerForm' );
		var validataFunc = function(){
			var validator = new Validator();
			validator.add( registerForm.userName, [{
				strategy: 'isNonEmpty',
				errorMsg: '用户名不能为空'
			}, {
				strategy: 'minLength:6',
				errorMsg: '用户名长度不能小于10 位'
			}]);
			validator.add( registerForm.password, [{
				strategy: 'minLength:6',
				errorMsg: '密码长度不能小于6 位'
			}]);
			var errorMsg = validator.start();
			return errorMsg;
		}
		registerForm.onsubmit = function(){
			var errorMsg = validataFunc();
			if ( errorMsg ){
				alert ( errorMsg );
				return false;
			}

		};
	</script>
</body>

</html>


首先,使用策略模式会在程序中增加许多策略类或者策略对象,但实际上这比把它们负责的逻辑堆砌在Context 中要好。

要使用策略模式,必须了解所有的strategy,必须了解各个strategy 之间的不同点,这样才能选择一个合适的strategy。比如,我们要选择一种合适的旅游出行路线,必须先了解选择飞机、火车、自行车等方案的细节。此时strategy 要向客户暴露它的所有实现,这是违反最少知识原则的。


Peter Norvig 在他的演讲中曾说过:“在函数作为一等对象的语言中,策略模式是隐形的。strategy 就是值为函数的变量。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值