策略模式:定義一系列的演算法,把它們一個個封裝起來,並且使它們可以相互替換
應用場景1
表單校驗
- 未使用策略模式
var registerForm = document.getElementById( 'registerForm' );
registerForm.onsubmit = function(){
if ( registerForm.userName.value === '' ){
alert ( '使用者名稱不能為空' );
return false;
}
if ( registerForm.password.value.length < 6 ){
alert ( '密碼長度不能少於 6 位' );
return false;
}
if ( !/(^1[3|5|8][0-9]{9}$)/.test( registerForm.phoneNumber.value ) ){
alert ( '手機號碼格式不正確' );
return false;
}
}
複製程式碼
- 使用策略模式
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;
}
}
};
var Validator = function(){
this.cache = []; // 儲存校驗規則
};
Validator.prototype.add = function(
var ary = rule.split( ':' );
this.cache.push(function(){ //
var strategy = ary.shift();
ary.unshift( dom.value );
ary.push( errorMsg ); //
return strategies[strategy].apply(dom, ary);
});
};
Validator.prototype.start = function(){
for ( var i = 0, validatorFunc; validatorFunc = this.cache[ i++ ]; ){
var msg = validatorFunc(); // 開始校驗,並取得校驗後的返回資訊
if ( msg ){ // 如果有確切的返回值,說明校驗沒有通過
return msg;
}
}
};
var validataFunc = function(){
var validator = new Validator(); // 建立一個 validator 物件
/***************新增一些校驗規則****************/
validator.add( registerForm.userName, 'isNonEmpty', '使用者名稱不能為空' );
validator.add( registerForm.password, 'minLength:6', '密碼長度不能少於 6位');
validator.add( registerForm.phoneNumber, 'isMobile', '手機號碼格式不正確' );
var errorMsg = validator.start(); // 獲得校驗結果
return errorMsg; // 返回校驗結果
}
var registerForm = document.getElementById( 'registerForm' ); registerForm.onsubmit = function(){
var errorMsg = validataFunc(); // 如果 errorMsg 有確切的返回值,說明未通過校驗
if ( errorMsg ){
alert ( errorMsg );
return false; // 阻止表單提交
}
};
複製程式碼
應用場景2
獎金計算,績效為 S 的人年 終獎有 4 倍工資,績效為 A 的人年終獎有 3 倍工資,而績效為 B 的人年終獎是 2 倍工資
- 未使用策略模式:
var calculateBonus = function( performanceLevel, salary ){
if ( performanceLevel === 'S' ){
return salary * 4;
}
if ( performanceLevel === 'A' ){
return salary * 3;
}
if ( performanceLevel === 'B' ){
return salary * 2;
}
};
calculateBonus( 'B', 20000 ); // 輸出:40000
calculateBonus( 'S', 6000 ); // 輸出:24000
複製程式碼
- 使用策略模式:
var strategies = {
"S": function( salary ){
return salary * 4;
},
"A": function( salary ){
return salary * 3;
},
"B": function( salary ){
return salary * 2;
}
};
var calculateBonus = function( level, salary ){
return strategies[ level ]( salary );
};
console.log( calculateBonus( 'S', 20000 ) );// 輸出:80000
console.log( calculateBonus( 'A', 10000 ) );// 輸出:30000
複製程式碼