资讯专栏INFORMATION COLUMN

JS设计模式-策略模式

mylxsw / 1447人阅读

摘要:策略模式是指对一系列的算法定义,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化。

策略模式是指对一系列的算法定义,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化。

优点:

策略模式利用组合、委托等技术和思想,可以避免很多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();
    }
}

这样实现的代码的缺点:

函数体积臃肿,包含了很多if判断

函数缺乏弹性,违反了开放-封闭原则

函数复用性差,如果增加表单需要类似验证,只能复制一遍

策略模式实现表单验证

// 策略对象
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 = []; //保存校验规则
    }

    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
    //添加一些校验规则
    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();
    }
}

策略模式属于对象行为模式,主要针对一组算法,将每一个算法封装到具有共同接口的独立的类中,使得它们可以相互替换。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/88923.html

相关文章

  • js设计模式--策略模式

    摘要:将不变的部分和变化的部分隔开是每个设计模式的主题,策略模式也不例外,策略模式的目的就是将算法的使用与算法的实现分离开来。 前言 本系列文章主要根据《JavaScript设计模式与开发实践》整理而来,其中会加入了一些自己的思考。希望对大家有所帮助。 文章系列 js设计模式--单例模式 js设计模式--策略模式 js设计模式--代理模式 概念 策略模式的定义是:定义一系列的算法,把它们一个...

    bigdevil_s 评论0 收藏0
  • JS 设计模式 十四(策略模式

    摘要:策略模式定义一系列的算法把它们一个个封装起来并且使它们可相互替换。策略模式要素策略接口,用来约束一系列具体的策略算法。策略模式策略购买辆总金额策略购买辆总金额策略模式优点算法可以自由切换。策略模式缺点策略类会增多。所有策略类都需要对外暴露。 策略模式 定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。策略模式是把一个类中经常改变或...

    sutaking 评论0 收藏0
  • JS策略模式《JavaScript设计模式与开发实践》阅读笔记

    摘要:策略模式可以避免代码中的多重判断条件。策略模式在程序中或多或少的增加了策略类。此文仅记录本人阅读设计模式与开发实践这个本时的感受,感谢作者曾探写出这么好的一本书。设计模式中很重要的一点就是将不变和变分离出来。参考设计模式与开发实践曾探 策略模式的定义是:定义一系列的算法,把它们一个个封装起来,并且是它们可以相互替换。 策略模式可以避免代码中的多重判断条件。 策略模式很好的体现了开放-...

    Amos 评论0 收藏0
  • JS设计模式——策略模式

    摘要:版本策略模式在上个例子中虽然初步实现了策略模式,但是是仿照的传统面向对象语言,而的实现更为简单,直接把原来的实例定义成函数,原先的类用函数来委托。 1. 介绍 策略模式是JS设计模式中一大重要的模式有着广泛的应用 2. 定义 定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换 3. 应用 根据等级、工资计算奖金等类似情况、使用不同的动画效果、表单验证等 4. 思想 把算法实...

    Jrain 评论0 收藏0
  • JavaScript 设计模式系列 - 策略模式与动态表单验证

    摘要:策略模式又称政策模式,其定义一系列的算法,把它们一个个封装起来,并且使它们可以互相替换。的表单具有表单验证功能,用来校验用户输入的表单内容。实际需求中表单验证项一般会比较复杂,所以需要给每个表单项增加自定义校验方法。 showImg(https://segmentfault.com/img/remote/1460000020135990); 策略模式 (Strategy Pattern...

    宋华 评论0 收藏0

发表评论

0条评论

mylxsw

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<