《JavaScript設計模式與開發實踐》模式篇(2)—— 策略模式

嗨呀豆豆呢發表於2018-12-11

策略模式:定義一系列的演算法,把它們一個個封裝起來,並且使它們可以相互替換

應用場景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
複製程式碼

系列文章:

《JavaScript設計模式與開發實踐》最全知識點彙總大全

相關文章