读书笔记-JavaScript设计模式与开发实践-策略模式

策略模式:定义一系列的算法,并且一个个封装起来,使得他们可以相互替换(达成一个目的可以有多种不同的方法)。
设计模式的目的就是将算法中不变的部分和变的部分分隔开来。

1 传统面向对象的策略模式实现

策略模式的程序至少由两部分组成。第一部分是一组策略类,封装了具体的算法,负责具体实现。第二部分是环境类Context,Context接受客户请求,随后将请求委托给某个策略类。下面代码中的是书中的策略模式例子:计算年终奖,年终奖根据基本工资和绩效计算,绩效有S、A、B,对应4、3、2倍工资,计算员工年终奖。

  • 1 先把每种绩效的计算规则封装到策略类里
     let perfomanceS = function () {};
    perfomanceS.prototype.calculate = function (salary) {
    return salary * 4
    };

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

    let perfomanceB = function () {};
    perfomanceB.prototype.calculate = function (salary) {
    return salary * 2
    };
  • 2 环境类Context,定义奖金类
     let 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 () { //取得奖金数额
    if (!this.strategy) {
    throw new Error('未设置strategy属性');
    }
    return this.strategy.calculate(this.salary); //把计算奖金的操作委托给对应的策略对象
    }
  • 3 调用计算年终奖
     let bonus = new Bonus();
    bonus.setSalary(10000);
    bonus.setStrategy(new perfomanceA()); //设置策略对象
    console.log(bonus.getBonus());
    策略模式就是定义一系列的算法(perfomanceS、A、B),把他们各自封装成策略类,算法被封装在策略类的内部方法里。在用户对环境类Context发起请求时,Context总是把请求委托给这些策略对象中的某一个进行计算。上述是基于传统面向对象语言的策略模式。

2 javascript的的策略模式

  • 1 前文中,我们模拟面向对象语言让策略对象从各个策略类中创建而来。在js中函数也是对象,可以直接把strategy定义为函数:
    let strategies = {
    'S': function (salary) {
    return salary * 4
    },
    'A': function (salary) {
    return salary * 3
    },
    'B': function (salary) {
    return salary * 2
    }
    };
  • 2 Context环境类也不一定要用Bonus类表示,用calculateBonus函数当作Context接受请求:
     let calculateBonus = function (level, salary) {
    return strategies[level](salary)
    };
  • 3 计算年终奖
    console.log(calculateBonus('S', 20000));

3 策略模式总结

在计算年中奖金例子中,Context类对这些策略对象发出‘计算奖金’的请求的时候,他们会返回不同的计算结果,这就是对象多态性的体现。接下来文中还介绍了两个策略模式的例子:小球各种模式移动和表单验证。小球移动是动画类根据不同的移动策略类中的策略对象来进行移动;表单验证是验证类根据不同的效验模式的策略对象进行效验。

策略模式优点有利用组合、委托、多态等技术避免重复的判断语句;提供了对开放-封闭原则对完美支持,将算法封装在独立的策略类中;高复用性;组合和委托让Context有执行算法的能力也是继承的一种轻便方案。缺点有会增加许多策略类和策略对象;使用的时候必须了解strange类。

在js中策略类可以很方便的用函数替代,和OOP语言实现有较大区别。

文章作者: 鐔雨
文章链接: https://caichunyu.github.io/2021/12/16/读书笔记-JavaScript设计模式与开发实践-策略模式/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 鐔雨的Blog