「JavaScript設計モードと開発実践」読書ノートの戦略モデル

9706 ワード

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文が含まれています.これらの文はすべてのブランチcallateBonus()関数をカバーする必要があります.拡張性が不足しています.パフォーマンスレベルCを追加すると、cacallteBonus()関数の内部実習を修正しなければなりません.開発-閉鎖原則に違反します.
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類はContectとして、ユーザーの要求を受けて、strateオブジェクトに委託します.
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;

        }

    }

};
ポリシーモードを使用すると、フォーム検証は構成によって完了できます.