设计模式----策略模式

定义:根据客观条件,选择不同方法(策略)达到目的

假设现在有一家公司,这个公司的加班情况很严重,但是老板还算有良心,原意支付加班工资。他规定,每月加班时长在0-10内,按1.2倍工资计算,10-20h内,按1.5倍计算,超过20h,按1.7倍工资计算。为了简化例子,我们不对加班时长进行分段计算所得。加班15小时,则所得加班费为15 * 1.5 * 基本工资/h。

对于上述例子,我们使用JavaScript可以很容易实现计算过程:

function CalculateOvertimePay (overtime, basePay){
  if (0 < overtime& overtime<= 10) {
    return 1.2 * overtime* basePay
  }else if (10 < overtime& overtime<= 20){
    return 1.5 * overtime * basePay
  }else{
    return 1.7 * overtime* basePay
  }
}

嗯。好像事情完成的很不错,这个函数到目前为止完全能够胜任我们的需求。但是再次审视函数,发现内部的if语句可能会过于庞大,当然,本例中勉强还能接受。最让我们难以接收的是,每当老板对薪资计算提出了新的规则,比如30h以上1.8倍工资。我们就要修改这个函数,这明显违背了开放-封闭原则再者,如果我们需要在别处使用10-20h的加班工资计算方法,我们能做的只剩下复制粘贴了。这显然不符合一个优秀代码民工对自己的要求。我们得想办法改进它。那就让我们用策略模式来重构上述代码吧。

function Strategy0 (overtime, basePay) {
  return 1.2 * overtime* basePay
}

function Strategy1 (overtime, basePay) {
  return 1.5 * overtime* basePay
}

function Strategy2 (overtime, basePay) {
  return 1.7 * overtime* basePay
}


Strategies = [
  Strategy0, Strategy1, Strategy2
]

function Context () {

}

Context.prototype.setBasePay = function (basePay) {
  this.basePay = basePay
}

Context.prototype.setOvertime = function (overtime) {
  this.overtime = overtime
}

Context.prototype.setStrategyLevel = function (level) {
  this.level = level
}

Context.prototype.CalculateOvertimePay = function () {
  return Strategies [this.level] (this.overtime, this.basePay)
}


let context =  new Context()
context.setBasePay(1)
context.setOvertime(15)
context.setStrategyLevel(2)

console.log(context.CalculateOvertimePay()); // 25.5

上述,代码是我们重构得结果。当然,存在一些bug,比如我们要手动给出选择策略,可能与实际情况不符。比如加班15h,但是我选择Strategy0,这显然是有误的。再者,最终调用CalculateOvertimePay方法时,没对参数做检验。又或者这三个策略唯一的差别只是系数不同,完全可以合成一个函数等(真实情况下,计算方式肯定是不同的)。当然,这些并不影响我们对策略模式的理解,就姑且不考虑了。

上面代码里,我们对不同加班时长对应的计算规则,分别给出了三个函数(计算策略),将其用一个数组保存。这就对应我们的策略类Strategies。当然,我们还需要个环境类来接受请求,并把求解委托给策略类进行最终计算,这里的环境类对应Context

当我们用策略模式重构后,我们可以在不改变原有代码的情况下,引入新的计算规则(策略)。假设现在我们需要添加新的规则,加班时长超过30h,1.8倍工资。只需添加代码如下:

function Strategy4 (overtime, basePay) {
  return 1.8 * overtime* basePay
}

Strategies[3] = Strategy4
//---------------test---------------------
context.setBasePay(1)
context.setOvertime(40)
context.setStrategyLevel(3)

console.log(context.CalculateOvertimePay()); // 72

这样,我们就遵循了开放-封闭原则,在不改变原有代码的情况下,加入了新的计算规则。

使用策略模式能够让代码很好复用,如果有个部门很特殊,无论加班时长多少,都按1.5倍工资计算,我们直接调用函数Strategy1即可,再也不用苦哈哈的去复制粘贴了。


因为太懒,就不提供Java版本了,欢迎各位同道补充。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值