JavaScript设计模式中策略模式的使用方法

本文详细介绍了策略模式的概念,展示了如何通过封装算法来消除条件分支语句,以实现代码的灵活性和可扩展性。内容包括策略模式的组成、多态的体现、优点以及在计算奖金场景中的应用。通过两个改造方案,从函数组合到面向对象的策略模式,说明了如何减少代码复杂性和提高代码可维护性。最后,展示了JavaScript中使用策略模式计算奖金的例子。
摘要由CSDN通过智能技术生成

策略模式

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

简单来说是:定义一系列的算法,把它们各自封装成策略类,算法被封装在策略类内部的方法里,在客户对 Context 发起请求的时候,Context 总是把请求委托给这些策略对象中间的某一个进行计算。目的将算法的使用与算法的实现分离开来

策略模式组成组成

  1. 策略类:封装具体的算法,并负责具体的计算过程
  2. 环境类 Context,Context 接受客户的请求,随后把请求委托给某一个策略类。要做到这一点 Context 要维持对某个策略对象的引用。

多态在策略模式中的体现

每个策略对象负责的算法已被各自封装在对象内部,当我们发起计算奖金时,它们会返回不同的计算结果,这正是对象多态性的体现。替换 Context 中当前保存的策略对象,便能执行不同的算法得到我们想要的结果。

多态

  1. 同一操作作用于不同的对象上面,可以产生不同的解释和不同的执行结果。换句话说,给不同的对象发送同一个消息的时候,这些对象会根据这个消息分别给出不同的反馈。
  2. 多态思想:将“做什么”和“谁去做以及怎样去做”分离开来,也就是将“不变的事情”与“可能改变的事物”分离开来。把不变的部分隔离出来,把可变的部分封装起来,这样就给予了我们扩展程序的能力,程序看起来是可生长的,也是符合开放-封闭原则的。
  3. 根本作用:通过把过程化的条件分支语句转化为对象的多态性,从而消除这些条件分支语句。

策略模式的优点

  1. 利用组合、委托、多态等技术和思想,减少多重条件语句

  2. 符合开放封闭原则,把算法封装在独立的对象中,使得对象易于切换、易于理解、易于扩展

  3. 代码逻辑可复用,减少重复工作

    1. 将行为分布在各个对象中,并让这些对象各自负责自己的行为,这正是面向对象设计的优点。

    2. 例子: 计算绩效奖金

    const calculateBonus = function (level, salary) {
    if (level == "S") {
    return salary _ 4;
    } else if (level == "A") {
    return salary _ 3;
    } else if (level == "B") {
    return salary \* 2;
    } else {
    return salary;
    }
    };
    console.log(calculateBonus("S", 10000));

  1. 缺点:
    • 后期随着绩效种类的增加,calculateBonus 函数可能会越来越庞大
    • 实现起来简单方便,但是 if-else 很多,这些语句需要覆盖所有的逻辑分支
    • 函数缺乏弹性,修改必须深入函数内部逻辑才可以进行修改,不符合开放-封闭原则
改造方案一
  1. 使用组合函数重构代码
  2. 我们把各种算法封装到一个个的小函数里面。

const performanceS = function (salary) {
return salary _ 4;
};
const performanceA = function (salary) {
return salary _ 3;
};

const performanceB = function (salary) {
return salary \* 2;
};

const calulateBonus2 = function (level, salary) {
if (level === "S") {
return performanceS(salary);
} else if (level === "A") {
return performanceA(salary);
} else if (level === "B") {
return performanceB(salary);
} else {
return salary;
}
};
console.log(calulateBonus2("S", 10000));

  1. 没有解决最重要的问题:后期随着绩效种类的增加,calculateBonus 函数可能会越来越庞大
改造方法二
面向对象的策略模式

const PS = function () {};
PS.prototype.calculate = function (salary) {
return salary _ 4;
};
const PA = function () {};
PA.prototype.calculate = function (salary) {
return salary _ 3;
};
const PB = function () {};
PB.prototype.calculate = function (salary) {
return salary \* 2;
};

const Bons4 = function () {
this.salary = null;
this.strategy = null; // 绩效等级对应的策略对象,
};

Bons4.prototype.setSalary = function (salary) {
this.salary = salary; // 设置原始工资
};
Bons4.prototype.setStrategy = function (strategy) {
this.strategy = strategy; // 设置绩效等级对应的策略对象,
};
Bons4.prototype.getBons4 = function () {
return this.strategy.calculate(this.salary); // 设置绩效等级对应的策略对象,
};

const bonus4 = new Bons4();
bonus4.setSalary(10000);
bonus4.setStrategy(new PS());
console.log(bonus4.getBons4());
Javascript 计算奖金版本的策略模式,

在 JavaScrpt 中,函数也是对象,简单直接的做法是把 strategy 直接定义为函数



const strategire = {
S: function (salary) {
return salary _ 4;
},
A: function (salary) {
return salary _ 3;
},
B: function (salary) {
return salary \* 2;
},
};
// 2. Context 接受用户的请求
const calulateBonus3 = function (level, salary) {
return strategire[level](salary);
};
console.log(calulateBonus3("S", 10000));
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值