《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;

        }

    }

};

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

 

你可能感兴趣的:(JavaScript)