《JavaScript设计模式与开发实践》模式篇(2)—— 策略模式

2,830

策略模式:定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换

应用场景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设计模式与开发实践》最全知识点汇总大全