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

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

假设现在有一家公司,这个公司的加班情况很严重,但是老板还算有良心,原意支付加班工资。他规定,每月加班时长在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
    评论
Java设计模式是一组经过实践验证的面向对象设计原则和模式,可以帮助开发人员解决常见的软件设计问题。下面是常见的23种设计模式: 1. 创建型模式(Creational Patterns): - 工厂方法模式(Factory Method Pattern) - 抽象工厂模式(Abstract Factory Pattern) - 单例模式(Singleton Pattern) - 原型模式(Prototype Pattern) - 建造者模式(Builder Pattern) 2. 结构型模式(Structural Patterns): - 适配器模式(Adapter Pattern) - 桥接模式(Bridge Pattern) - 组合模式(Composite Pattern) - 装饰器模式(Decorator Pattern) - 外观模式(Facade Pattern) - 享元模式(Flyweight Pattern) - 代理模式(Proxy Pattern) 3. 行为型模式(Behavioral Patterns): - 责任链模式(Chain of Responsibility Pattern) - 命令模式(Command Pattern) - 解释器模式(Interpreter Pattern) - 迭代器模式(Iterator Pattern) - 中介者模式(Mediator Pattern) - 备忘录模式(Memento Pattern) - 观察者模式(Observer Pattern) - 状态模式(State Pattern) - 策略模式(Strategy Pattern) - 模板方法模式(Template Method Pattern) - 访问者模式(Visitor Pattern) 4. 并发型模式(Concurrency Patterns): - 保护性暂停模式(Guarded Suspension Pattern) - 生产者-消费者模式(Producer-Consumer Pattern) - 读写锁模式(Read-Write Lock Pattern) - 信号量模式(Semaphore Pattern) - 线程池模式(Thread Pool Pattern) 这些设计模式可以根据问题的特点和需求来选择使用,它们提供了一些可复用的解决方案,有助于开发高质量、可维护且易于扩展的软件系统。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值