前端策略模式

前端策略模式


一、策略模式的优缺点

策略模式是一种常用且有效的设计模式,本章提供了计算奖金、缓动动画、表单校验这三个
例子来加深大家对策略模式的理解。从这三个例子中,我们可以总结出策略模式的一些优点。
 策略模式利用组合、委托和多态等技术和思想,可以有效地避免多重条件选择语句。
 策略模式提供了对开放—封闭原则的完美支持,将算法封装在独立的 strategy 中,使得它
们易于切换,易于理解,易于扩展。
 策略模式中的算法也可以复用在系统的其他地方,从而避免许多重复的复制粘贴工作。
 在策略模式中利用组合和委托来让 Context 拥有执行算法的能力,这也是继承的一种更轻
便的替代方案。
当然,策略模式也有一些缺点,但这些缺点并不严重。
首先,使用策略模式会在程序中增加许多策略类或者策略对象,但实际上这比把它们负责的
逻辑堆砌在 Context 中要好。
其次,要使用策略模式,必须了解所有的 strategy,必须了解各个 strategy 之间的不同点,
这样才能选择一个合适的 strategy。比如,我们要选择一种合适的旅游出行路线,必须先了解选
择飞机、火车、自行车等方案的细节。此时 strategy 要向客户暴露它的所有实现,这是违反最少
知识原则的。

二、策略模式的定义

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

三、策略模式的使用

策略模式有着广泛的应用。本节我们就以年终奖的计算为例进行介绍。
很多公司的年终奖是根据员工的工资基数和年底绩效情况来发放的。例如,绩效为 S 的人年
终奖有 4 倍工资,绩效为 A 的人年终奖有 3 倍工资,而绩效为 B 的人年终奖是 2 倍工资。假设财
务部要求我们提供一段代码,来方便他们计算员工的年终奖。

1.最初的代码实现

我们可以编写一个名为 calculateBonus 的函数来计算每个人的奖金数额。很显然,calculateBonus 函数要正确工作,就需要接收两个参数:员工的工资数额和他的绩效考核等级。
代码如下:

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 函数的内部实现,这是违反开放封闭原则的。
 算法的复用性差,如果在程序的其他地方需要重用这些计算奖金的算法呢?我们的选择只有复制和粘贴。
因此,我们需要重构这段代码

2.使用策略模式重构代码

经过思考,我们想到了更好的办法——使用策略模式来重构代码。策略模式指的是定义一系列的算法,把它们一个个封装起来。将不变的部分和变化的部分隔开是每个设计模式的主题,策略模式也不例外,策略模式的目的就是将算法的使用与算法的实现分离开来。在这个例子里,算法的使用方式是不变的,都是根据某个算法取得计算后的奖金数额。而算法的实现是各异和变化的,每种绩效对应着不同的计算规则。一个基于策略模式的程序至少由两部分组成。第一个部分是一组策略类,策略类封装了具体的算法,并负责具体的计算过程。第二个部分是环境类 Context,Context 接受客户的请求,随后把请求委托给某一个策略类。要做到这点,说明 Context 中要维持对某个策略对象的引用。现在用策略模式来重构上面的代码。第一个版本是模仿传统面向对象语言中的实现。我们先把每种绩效的计算规则都封装在对应的策略类里面

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

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值