《JavaScript设计模式与开发实践》读书笔记之策略模式

1.策略模式

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

1.1 传统实现

根据工资基数和年底绩效来发送年终奖

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

calculateBonus()函数包含了很多if-else语句,这些语句需要覆盖所有分支
calculateBonus()函数缺乏扩展性,如果新增一个绩效等级C,必须修改calculateBonus()函数内部实习,违反开发-封闭原则

1.2 使用策略模式重构代码

传统面向对象模式的策略模式

var performanceS= function () {};
performanceS().prototype.calculate= function (salary) {
    return salary *4;
};

var performanceA=function(){};
performanceA().prototype.calculate=function(salary){
    return salary * 3;
};

var Bonus= function () {
    this.salary=null;
    this.strategy=null;
};
Bonus.prototype.setSalary= function (salary) {
    this.salary=salary;
};
Bonus.prototype.setStrategy=function(strategy){
    this.strategy=strategy;
};
Bonus.prototype.getBonus= function () {
    return this.strategy.calculate(this.salary);
};

var bonus=new Bonus();
bonus.setSalary(1000);
bonus.setStrategy(new performanceS());
console.log(bonus.getBonus()());//输出40000

1.3 JavaScript版本的策略模式

var strategies={
  "S": function (salary) {
      return salary*4;
  },
  "A": function (salary) {
      return salary*3;
  },
  "B": function (salary) {
      return salary*2;
  }
};
//calculateBonus充当Context来接受用户请求
var calculateBonus= function (level,salary) {
    return strategies[level](salary);
};
console.log(calculateBonus('S',2000));//输出8000

1.4 用策略模式来重构表单校验

 

校验规则
用户名不能为空
密码长度不能少于6位
手机号码必须符合格式

var strategise={
    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;
        }
    }
};

Validateor类作为Context,负责接收用户请求,并委托给strategy对象

var validataFunc= function () {
    var validator=new Validator();

    //添加校验规则
    validator.add(form.userName,'isNonEmpty','用户名不能为空');
    validator.add(form.password,'minLength:6','密码长度不能少于6位');
    validator.add(form.phoneNumber,'isMobile','手机号码格式不正确');
    var errorMsg=validator.start();
    return errorMsg;
};

var form =document.getElementById('form');
form.onsubmit= function () {
    var errorMsg=validataFunc();
    if(errorMsg){
        alert(errorMsg);
        return false;
    }
};

var Validator= function () {
    this.cache=[];
};
Validator.prototype.add= function (dom,rule,errorMsg) {
    var ary=rule.split(':');//把strategy算法和参数分开
    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;
        }
    }
};

使用策略模式,可以通过配置方式完成表单校验

 

posted @ 2015-07-16 15:45  GongQi  阅读(252)  评论(0编辑  收藏  举报