JavaScript设计模式—-策略模式[通俗易懂]

JavaScript设计模式—-策略模式[通俗易懂]声明:这个系列为阅读《JavaScript设计模式与开发实践》—-曾探@著一书的读书笔记1.策略模式的定义将不变的部分和变化的部分隔开是每个设计模式的主题。定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换。2.策略模式的目的将算法的使用与算法的实现分离开来。3.传统语言中的策略模式和JavaScript中的策略模式对比3.1.传统语言中的策略模式使用策略模式来实现计算奖金v

大家好,又见面了,我是你们的朋友全栈君。

声明:这个系列为阅读《JavaScript设计模式与开发实践》 —-曾探@著一书的读书笔记

1.策略模式的定义

将不变的部分和变化的部分隔开是每个设计模式的主题。

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

2.策略模式的目的

将算法的使用与算法的实现分离开来。

3.传统语言中的策略模式和JavaScript中的策略模式对比

3.1.传统语言中的策略模式

使用策略模式来实现计算奖金


var performances = function () { 
   };

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

var performanceA =function () { 
   };

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

var performanceB =function () { 
   };

performanceB.prototype.calculate=function (salary) { 
   
    return salary * 2;
};

//定义奖金类Bonus

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(10000);
bonus.setStrategy(new performances());//设置策略对象

console.log(bonus.getBonus());

bonus.setStrategy(new performanceA());

console.log(bonus.getBonus());

定义有系列的算法,把它们各自封装成策略类,算法被封装在策略类内部的方法里。在客户端对Context发起请求的时候,Context总是把请求委托给这些策略对象中间的某一个进行计算。

3.2.JavaScript中的策略模式


//封装的策略算法
var strategies={
    "S":function (salary) { 
   
        return salary * 4;
    },
    "A":function (salary) { 
   
        return salary * 3;
    },
    "B":function (salary) { 
   
        return salary * 2;
    }
};


//具体的计算方法
var calculateBonus=function (level, salary) { 
   
    return strategies[level](salary);
};

console.log(calculateBonus('S',1000));
console.log(calculateBonus('A',4000));

使用策略模式重构代码,可以消除程序中大片的条件分支语句。在实际开发中,我们通常会把算法的含义扩散开来,使策略模式也可以用来封装一系列的“业务规则”。只要这些业务规则指向的目标一致,并且可以被替换使用,我们就可以使用策略模式来封装他们。

4.策略模式实现的表单校验

4.1使用JavaScript来实现的一个支持多重校验规则表单校验

//策略对象

var strategies = {
    isNonEmpty: function (value, errorMsg){ 
   
        if (value === '') {
            return errorMsg;
        }
    },
    minLength: function (value, length, errorMg){ 
   
        if (value.length < length) {
            return errorMg;
        }
    },
    isMobile: function (value, errorMsg){ 
   
        if (!/(^1[3|5|8][0-9]{9}$)/.test(value)) {
            return errorMsg;
        }
    }
};



/** * Validator 类 * @constructor */
var Validator = function (){ 
   
    this.cache = [];
};

Validator.prototype.add = function (dom, rules){ 
   
    var self = this;

    for (var i = 0, rule; rule = rules[i++];) {
        (function (rule){ 
   
            var strategyAry=rule.strategy.split(':');
            var errorMsg=rule.errorMsg;

            self.cache.push(function (){ 
   
                var strategy=strategyAry.shift();
                strategyAry.unshift(dom.value);
                strategyAry.push(errorMsg);
                return strategies[strategy].apply(dom,strategyAry);
            })
        })(rule)
    }
};

Validator.prototype.start=function (){ 
   
    for (var i=0,validatorFunc;validatorFunc=this.cache[i++];){
        var errorMsg=validatorFunc();
        if(errorMsg){
            return errorMsg;
        }
    }
};

//客户端调用的代码

var registerForm=document.getElementById('registerForm');
var validataFunc=function (){ 
   
    var validator=new Validator();

    validator.add(registerForm.userName,[{
        'strategy':'isNonEnpty',
        'errorMsg':'用户名不能为空'
    },{
        'strategy':'minLength',
        'errorMsg':'用户名长度不能小于10位'
    }]);

    // validator.add(registerForm.password,[])

    var errorMsg =validator.start();
    return errorMsg;

};

registerForm.onsubmit=function (){ 
   
    var errorMsg=validataFunc();

    if(errorMsg){
        alert(errorMsg);
        return false;
    }
};

4.2策略模式的优缺点:

优点:

  • 策略模式利用组合,委托和多态等技术思想,可以有效的避免多重条件选择语句;
  • 策略模式提供了对开放-封闭原则的完美支持,将算法封装在独立的strategy中,使得它们易于切换,易于理解,易于扩展。
  • 策略模式中的算法也可以复用在系统的其它地方,从而避免许多重复的复制粘贴工作。
  • 在策略模式中利用组合和委托来让Context拥有执行算法的能力,这也是继承的一种更轻便的替代方案。

缺点:

  • 策略模式会在程序中添加许多的策略类和策略对象
  • 要使用策略模式,就必须要了解各个strategy和他们之间的不同点,这样才能选择一个合适的strategy

4.3函数多态性的描述

在函数作为一等对象的语言中,策略模式是隐形的。strategy就是值为函数的变量。

在JavaScript中,除了使用类来封装算法和行为之外,使用函数当然也是一种选择。这些“算法”可以被封装到函数中并且四处传递,也就是我们常说的“高阶函数”。

实际上在JavaScript这种将函数作为一等对象的语言里,策略模式已经融入到了语言本身当中,我们经常使用高阶函数来封装不同的行为,并且把它传递到另一个函数中。当我们对这些函数发出“调用”的消息时,不同的函数会返回不同的执行结果。所以在JavaScript中,“函数对象的多态性”会更加简单些。

总结:

在JavaScript语言的策略模式中,策略类往往被函数所代替,这时策略模式就成了一种“隐形”的模式。


图片名称

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/158214.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • Java常见设计模式总结

    Java常见设计模式总结

    2021年10月5日
    36
  • Java常用设计模式

    Java常用设计模式一、设计模式概念1、定义​Java包含23种设计模式,是一套对代码设计经验的总结,被人们反复利用,多人熟知的代码设计方式。2、目的​为了提高代码的可读性,可扩展性以及代码的复用性,为了解决在写代码过程中遇到的代码设计问题。3、设计模式的六大原则​3.1开闭原则​对扩展开放,对修改关闭(尽可能对代码少修改)​3.2里氏替换原则​它是面向对象基本原则之一,任何父类(基类)出现的地方,子类都可以出现,也就是子类可以替换父类的任何功能(体现了父类的可扩展性)3.3依赖

    2022年7月8日
    24
  • [设计模式]委派模式「建议收藏」

    github地址:https://github.com/1711680493点我进入github如需了解更多设计模式,请进入我的设计模式专栏委派模式委派模式不是23设计模式中的一种.与策略模式很相似.拥有以下三种角色抽象任务角色 委派者角色 具体任务角色委派模式,就是将任务发给委派者角色,委派者角色去委派具体任务角色委派模式对外隐藏了具体实现,仅将委派者角色暴露给外部委派模式和策略模式不同的是,委派者角色和具体任务角色都要继承/实现抽象任务角色Spring框架很

    2022年4月16日
    41
  • 设计模式之桥接(bridge)模式

    在现实生活中,我们常常会用到两种或多种类型的笔,比如毛笔和蜡笔。假设我们需要大、中、小三种类型的画笔来绘制12中不同的颜色,如果我们使用蜡笔,需要准备3*12=36支。但如果使用毛笔的话,只需要提供3

    2021年12月19日
    51
  • php设计模式之工厂模式

    php设计模式之工厂模式工厂模式的学习

    2022年7月25日
    9
  • java设计模式1,单一职责原则

    java设计模式1,单一职责原则单一职责原则就是指一个类或者模块应该有且只有一个改变的原因。

    2025年6月11日
    4

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号