「这是我参与2022首次更文挑战的第16天,活动详情查看:2022首次更文挑战」
在学习中有这样一段话:在学一样东西的时候,可以按照它是什么,有什么用,优点是什么,缺点是什么,要怎么去使用,或者使用的时候要注意什么。我觉得这五部曲还是很有用的,能帮你快速掌握一个知识点
策略模式是什么?
策略模式(Strategy Pattern)的定义:
该模式定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响使用算法的客户。策略模式属于对象行为模式,它通过对算法进行封装,把使用算法的责任和算法的实现分割开来,并委派给不同的对象对这些算法进行管理。
简单的来说,就是把我们平时常用的一些判断语句作为策略封装起来,这样就能够做到多次复用,并且之后如果需要修改,也能够统一修改策略,而不需要去改动使用的地方。
策略模式有什么用?
解决了条件判断过程中,if else 过于臃肿的问题
相信大家一开始在写代码的时候,没少碰到过这样子的情况:
或者是这样子的
以上代码实现逻辑和功能都是没有问题的,就是违反了我们软件设计的开闭原则:当应用的需求改变时,在不修改软件实体的源代码或者二进制代码的前提下,可以扩展模块的功能,使其满足新的需求。
一旦之后我要加入 条件C,那么就必须来改动这部分代码,如果之后的条件越来越多,或者说用到这个相同判断的地方不止一个,比如说这是一个注册表单的验证,那么在很多地方都要做出一样的验证,如果像上述的 if else 写法,那么一旦验证条件增加,或者验证逻辑修改,那么很多地方的代码都要被改动。
所以我们可以使用策略模式来包装这部分代码,使得维护变得简易
策略模式的优点?
-
多重条件语句不易维护,而使用策略模式可以避免使用多重条件语句,如 if...else 语句、switch...case 语句。
-
策略模式中存在不同的算法类,可以编写不同算法类公共的父类存放相同的算法逻辑,避免重复的代码。
-
满足开闭原则的要求,将算法和实现分离,在不改动原代码的情况下,灵活增加新算法。
策略模式的缺点?
-
因为将所有算法都进行了外部封装,所有使用的时候就必须要知道每个算法的作用和区别,用于选择适合的算法类。
-
策略模式算法过多也会造成过多的策略类,增加维护难度。
那么策略模式在实际的代码当中要怎么去使用呢?
我们用一个购物事件来模拟一下需求,现在有普通会员,白银会员和黄金会员,他们买东西拿到的折扣分别是 九折 八折 七折,那么我们就需要三个策略对象,他们有着他们自己的计算逻辑,计算价格的时候,只管将值传给对应的策略对象,让他们自己去计算他们所需要的真实价格。
/**
* 策略类
*/
// 普通会员卡
class CommonCard {
calculate(price) {
return price * 0.9;
}
}
// 白银会员卡
class SilverCard {
calculate(price) {
return price * 0.8;
}
}
// 黄金会员卡
class GlodCard {
calculate(price) {
return price * 0.7;
}
}
/**
* 环境类Context
*/
class Shopping {
constructor() {
this.strategy = null; // 会员等级对应的策略对象
}
// 设置对应会员卡需要的策略对象
setStrategy(strategy) {
this.strategy = strategy;
}
// 获取实际金额
getBonus(price) {
return this.strategy.calculate(price); // 把计算金额的操作委托给对应的策略对象
}
}
let shopping = new Shopping();
shopping.setStrategy(new CommonCard()); // 普通会员卡
console.log(shopping.getBonus(100)); // 输出:90
shopping.setStrategy(new SilverCard()); // 白银会员卡
console.log(shopping.getBonus(100)); // 输出:80
shopping.setStrategy(new GlodCard()); // 黄金会员卡
console.log(shopping.getBonus(100)); // 输出:70
这样我们就实现了一个简单的策略模式,每个策略对象中还可以有着更多的计算逻辑,并且他们可以有着共同的父类,父类中可以放置大家公用的计算逻辑,比如上方三个策略对象的父类可以是一个会员类,里面定义了会员能够拥有的基本权益,子类中可以对这些权益进行覆盖,这样就可以有效的减少代码的重复。
总结
在日常的代码编辑当中,如果碰到了过多的 if else 的现象,那么就可以考虑使用策略模式来做一个代替,这样可以避免之后添加逻辑判断的不方便,更加有利于之后的代码维护。