设计模式-策略模式

文章介绍了策略模式的概念,通过将不同的算法封装成独立的策略类,允许在运行时选择和切换算法。以计算员工年终奖为例,从最初的条件判断实现,转换为使用组合函数和最终的策略模式实现,展示了如何通过策略模式提高代码可读性和可维护性。
摘要由CSDN通过智能技术生成

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

详细解释:定义一系列的算法,把它们各自封装成策略类,算法被封装在策略类内部的方法里。

应用场景:

  • 缓动动画

  • 验证表单

优点:

  • 策略模式利用组合、委托和多态等技术和思想,可以有效地避免多重条件选择语句。

  • 策略模式提供了对开放-封闭原则的完美支持,将算法封装在独立的strategy中,使得它们易于切换,易于理解,易于拓展。

  • 策略模式中的算法也可以复用在系统的其他地方,从而避免许多的复制粘贴工作。

  • 在策略模式中利用组合和委托来让Context拥有执行算法的能力,这也是继承的一种更轻便的替代方案。

缺点:

  • 使用策略模式会在程序中增加许多策略类或者策略对象,但实际上这比吧它们负责的逻辑堆砌在Context中要好。

  • 要使用策略模式,必须了解所有的strategy,必须了解各个strategy之间的不同点,这样才能选择一个合适的strategy。比如,我们要选择一种合适的旅游路线,必须先了解选择飞机、火车、自行车等方案的细节。此时strategy要向客户暴露它的所有实现,这是违反最少知识原则的。

// 计算奖金 - 绩效为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

// 使用组合函数重构代码 - 我们把各种算法封装到一个个小函数里面,这些小函数有着良好的命名,可
// 以一目了然地知道它对应着哪种算法。他们也可以被复用在程序的其他地方。
var performanceS = function(salary){
    return salary * 4
}
var performanceA = function(salary){
    return salary * 3
}
var performanceB = function(salary){
    return salary * 2
}
var calculateBonus = function(performanceLevel, salary){
    if(performanceLevel === 'S'){
        return performanceS(salary)
    }  
    if(performanceLevel === 'A'){
        return performanceA(salary)
    } 
    if(performanceLevel === 'B'){
        return performanceB(salary)
    }   
}
calculateBonus('A', 10000) // 30000

// 使用策略模式重构代码 - 一个基于策略模式的程序至少由两部分组成。第一部分是一组策略类,策
// 略类封装了具体的算法,并负责具体的计算过程。第二个部分是环境类Context,Context接受客户
// 的请求,随后把请求委托给某一个策略类。
// (模仿传统面向对象语言中的实现)
var performanceS = function(){}
performanceS.prototype.calculate = function(salary){
    return salary * 4
}
var performanceA = function(){}
performanceA.prototype.calculate = function(salary){
    return salary * 3
}
var performanceB = function(){}
performanceB.prototype.calculate = function(salary){
    return salary * 2
}
var 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) //委托给对应的策略类
}
var bonus = new Bonus()
bonus.setSalary(10000)
bonus.setStrategy(new performanceS)
console.log(bonus.getBonus()) // 40000
bonus.setStrategy(new performanceA)
console.log(bonus.getBonus()) // 30000

// JavaScript版本的策略模式
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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值