从计算年终奖开始,理解策略模式 - 2/14

简介: 从计算年终奖开始,理解策略模式 - 2/14

从计算年终奖开始,理解策略模式 - 2/14


首先,先想下怎么实现这样一个功能。

很多公司的年终奖是根据员工的工资基数和年底绩效情况来发放的。

例如,绩效为 S 的人年终奖有 4 倍工资,绩效为 A 的人年终奖有 3 倍工资,而绩效为 B 的人年终奖是 2 倍工资。

假设财务部要求我们提供一段代码,来方便他们计算员工的年终奖。

想想。。。

想想。。。

想想。。。

计算奖金--初始想法

可能多数人的第一反应是下面的

var calculateBonus = function(performanceLevel, salary) {
  if (performanceLevel === "S") {
    return salary * 4;
  }
  if (performanceLevel === "A") {
    return salary * 3;
  }
  if (performanceLevel === "B") {
    return salary * 2;
  }
};
calculateBonus("B", 20000); // 输出:40000
calculateBonus("S", 6000); // 输出:24000

看起来完美得很。但实际有很多缺点:

  • calculateBonus 函数比较庞大,包含了很多 if-else 语句,这些语句需要覆盖所有的逻辑 分支。
  • calculateBonus 函数缺乏弹性,如果增加了一种新的绩效等级 C,或者想把绩效 S 的奖金系数改为 5,那我们必须深入 calculateBonus 函数的内部实现,这是违反开放  封闭原则的。
  • 算法的复用性差,如果在程序的其他地方需要重用这些计算奖金的算法呢?我们的选择只有复制和粘贴。

来,再想想,怎么改进?

来,再想想,怎么改进?

来,再想想,怎么改进?

计算奖金---升级版

大逻辑:将各个评级的计算方法封装起来,然后写个对象,将评级和计算方式一一对应,使用的时候就传入评级就好。 代码如下:

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", 20000)); // 输出:80000
console.log(calculateBonus("A", 10000)); // 输出:30000

优点:

  • 增加等级,只需在策略里增加算法就好
  • 增加等级,calculateBonus函数也不需要修改
  • 赏心悦目

初步理解策略模式

策略模式:封装一系列的算法,根据情况调用不同的算法,目的是将算法的实现算法的使用分离开来,本质上就是将变与不变剥开。

拿年终奖来说:

  • strategies是算法的实现,封装了一系列的算法
  • calculateBonus是算法的使用

以后碰到很多if/else的时候,想想这种改进方式。

策略模式的优缺点

优点:

  • 策略模式可以有效地避免if
  • 策略模式算法独立封装,易于理解和于扩展
  • 算法可以复用在其他地方

缺点:封装算法和必须了解所有算法

在前面的学习中,为了清楚地表示这是一个策略模式,我们特意使用了strategies 这个名字。

如果去掉strategies,我们还能认出这是一个策略模式的实现吗?代码如下:

var S = function( salary ){
    return salary * 4;
};
var A = function( salary ){
    return salary * 3;
};
var B = function( salary ){
    return salary * 2;
};
var calculateBonus = function( func, salary ){
    return func( salary );
};
calculateBonus( S, 10000 ); // 输出:40000

引用

  • 《JavaScript的设计模式和开发实践》
目录
相关文章
|
6天前
|
设计模式 人工智能 前端开发
像品茶一样品设计模式,早日突破编码新境界。
设计模式在日常开发中虽非必需,但对解决复杂问题、提升代码质量至关重要。通过多个实际场景的分析,如会员卡系统、代码评审和AI视频编辑器等,展示了设计模式的重要性。学习设计模式不仅能提高代码的可读性和扩展性,还能为框架源码阅读和面试提供支持。其核心目标是实现高复用和易扩展的应用程序,遵循封装、面向接口、组合优于继承等基本原则,并遵守SOLID原则。前端开发者应掌握单例模式、工厂模式、装饰器模式等经典设计模式,以应对不同项目需求。总结而言,设计模式是一把双刃剑,需根据具体问题灵活运用,适合项目环境的设计模式才是最好的。 (239字符)
|
8月前
【错题集-编程题】买卖股票的最好时机(一)(贪心 + 动态规划)
【错题集-编程题】买卖股票的最好时机(一)(贪心 + 动态规划)
|
8月前
|
存储
面向对象技术(第二周)
面向对象技术(第二周)
|
8月前
|
设计模式 Java 开发者
避免重复代码的灾难:Java设计模式的救赎之路
【4月更文挑战第7天】设计模式是解决编程问题的模板,提供整洁、可扩展的代码结构。如单例模式确保唯一实例,工厂方法模式实现对象创建的标准化。其他模式如抽象工厂、建造者、原型、适配器、观察者等,分别用于生成相关对象、复杂对象构建、接口兼容、消息传递等场景。掌握设计模式能提升代码质量,使开发更高效,是Java开发者必备技能。
44 0
|
设计模式 存储 算法
2023-7-8-第十四式策略模式
2023-7-8-第十四式策略模式
92 0
|
8月前
|
算法
犯错总结--工厂模式和策略模式傻傻没分清
犯错总结--工厂模式和策略模式傻傻没分清
66 0
犯错总结--工厂模式和策略模式傻傻没分清
挤奶牛奶预备事项(应用的数学分析,贪心思想)
挤奶牛奶预备事项(应用的数学分析,贪心思想)
52 0
装饰模式实例复杂的奖金计算
装饰模式实例复杂的奖金计算
132 0
装饰模式实例复杂的奖金计算
|
算法 前端开发
|
Java
【蓝桥Java每日一题】——11.做菜顺序(贪心秒杀困难题)
今天给大家带来一道级别是困难的力扣题,但是利用贪心思想我们可以很快速地做出来,甚至称之为简单题也不为过,可见贪心之强大
216 0