JS設計模式-策略模式


策略模式是指對一系列的算法定義,并將每一個算法封裝起來,而且使它們還可以相互替換。策略模式讓算法獨立于使用它的客戶而獨立變化。

原文鏈接
優(yōu)點:

  • 策略模式利用組合、委托等技術和思想,可以避免很多if條件語句
  • 策略模式提供了開放-封閉原則,使代碼更容易理解和拓展

簡單取值

很多例子?以績效等級和薪資計算獎金為?說明

let calculateBouns = (level,salary)=>{
    if(level=='A'){
        return salary * 1.4;
    }else if(level=='B'){
        return salary * 1.3;
    }else if(level=='C'){
        return salary * 1.2;
    }else{
        return salary;
    }
}

console.log(calculateBouns('A', 8000)); //11200
console.log(calculateBouns('C', 8000)); //9600

策略模式重構

//策略對象
class ruleA{
    calculate(salary){
        return salary * 1.4;
    }
} 

class ruleB{
    calculate(salary){
        return salary * 1.3;
    }
} 

class ruleC{
    calculate(salary){
        return salary * 1.2;
    }
} 

//獎金類
class Bouns{
    constructor(){
        this.salary = null;
        this.level = null;
    }

    setLevel(level){
        this.level = level;
    }

    setSalary(salary){
        this.salary = salary;
    }

    getBouns(){
        return this.level.calculate(this.salary);
    }
}

let tom = new Bouns(),jerry = new Bouns();
//設置薪資
tom.setSalary(8000);
jerry.setSalary(10000);
//設置策略對象
tom.setLevel(new ruleA());
jerry.setLevel(new ruleA());
console.log(tom.getBouns()); //11200
console.log(jerry.getBouns()); //14000

jerry.setLevel(new ruleB());
console.log(jerry.getBouns()); //13000

表單

還有一種?理解策略模式的例子就是表單驗證,通常會涉及到多個字段有效性判斷

let form = document.getElementById("Form");
form.onsubmit = function(){
    if(form.username.value == ''){
        alert('用戶名不能為空');
        return false;
    }else if(form.username.value.length <= 6){
        alert('用戶名長度不能小于6位');
        return false;
    }else if(form.password.value.length <= 6){
        alert('密碼長度不能小于6位');
        return false;
    }else if(!/(^1[3|5|8][0-9]{9}$)/.test(form.phone.value)){
        alert("手機號碼格式不正確");
        return;
    }else{
        submit();
    }
}

這樣實現(xiàn)的代碼的缺點:

  • 函數(shù)體積臃腫,包含了很多if判斷
  • 函數(shù)缺乏彈性,違反了開放-封閉原則
  • 函數(shù)復用性差,如果增加表單需要類似驗證,只能復制一遍

策略模式實現(xiàn)表單驗證

// 策略對象
let strategys = {
    isEmpty: (value,errorMsg)=> {
        if(value === '') {
            return errorMsg;
        }
    },
    // 限制最小長度
    minLength: (value,length,errorMsg)=> {
        if(value.length < length) {
            return errorMsg;
        }
    },
    // 手機號碼格式
    illegalPhone: (value,errorMsg)=> {
        if(!/(^1[3|5|8][0-9]{9}$)/.test(value)) {
            return errorMsg;
        }
    } 
};

class Validator{
    constructor(){
        this.cache = []; //保存校驗規(guī)則
    }

    addRule(dom,rules){
        var self = this;
        for(let i = 0, rule; rule = rules[i++]; ){
            let strategyAry = rule.strategy.split(":");
            let errorMsg = rule.errorMsg;
            self.cache.push(function(){
                let strategy = strategyAry.shift();
                strategyAry.unshift(dom.value);
                strategyAry.push(errorMsg);
                return strategys[strategy].apply(dom,strategyAry);
            });
        }
    }

    check(){
        for(let i = 0, fn; fn = this.cache[i++]; ) {
            let msg = fn(); // 開始效驗 并取得效驗后的返回信息
            if(msg) {
                return msg;
            }
        }
    }
}

// 代碼調用
let form = document.getElementById("Form");
let validateFunc = function(){
    let validator = new Validator(); // 實例化Validator
    //添加一些校驗規(guī)則
    validator.addRule(form.username,[
        {strategy: 'isEmpty',errorMsg:'用戶名不能為空'},
        {strategy: 'minLength:6',errorMsg:'用戶名長度不能小于6位'}
    ]);
    validator.addRule(form.password,[
        {strategy: 'minLength:6',errorMsg:'密碼長度不能小于6位'},
    ]);
    validator.addRule(form.phone,[
        {strategy: 'illegalPhone',errorMsg:'手機號格式不正確'},
    ]);
    return  validator.check();
};

form.onsubmit = function(){
    let errorMsg = validateFunc();
    if(errorMsg){
        alert(errorMsg);
        return false;
    }else{
        submit();
    }
}

策略模式屬于對象行為模式,主要針對一組算法,將每一個算法封裝到具有共同接口的獨立的類中,使得它們可以相互替換。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • 工廠模式類似于現(xiàn)實生活中的工廠可以產生大量相似的商品,去做同樣的事情,實現(xiàn)同樣的效果;這時候需要使用工廠模式。簡單...
    舟漁行舟閱讀 8,131評論 2 17
  • 原文收錄在我的 GitHub博客 (https://github.com/jawil/blog) ,喜歡的可以關注...
    微醺歲月閱讀 2,481評論 0 20
  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,653評論 19 139
  • 1. Java基礎部分 基礎部分的順序:基本語法,類相關的語法,內部類的語法,繼承相關的語法,異常的語法,線程的語...
    子非魚_t_閱讀 34,741評論 18 399
  • 各位好,我是園長大人。 前幾天和朋友聊天,她說她現(xiàn)在踏進了一個上流社會的圈子,圈子里的朋友如何有錢,其中一個人在北...
    限時游樂園club閱讀 457評論 0 0

友情鏈接更多精彩內容