策略模式學習筆記

平時咱們在寫代碼時會偶爾用到策略模式的思想,但咱們卻不自知。今天學習了策略模式,特記錄以下: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>

還能夠作成一個適合項目的校驗插件,方便調用。

策略模式還能夠有其餘使用場景:能夠用來封裝一系列的"業務規則",單出現不少判斷條件語句時,就能夠思考一下是否能夠使用策略模式。

若有錯誤,請指正!

相關文章
相關標籤/搜索