这是我参与8月更文挑战的第2天,活动详情查看:8月更文挑战。
前言
判断作为编程三种基本结构 (顺序、循环、判断) 之一,在日常开发中是常常会遇见的。如何去书写语句即是小白入门语法的体现,也是大佬优化的目标,那怎么才能写出让人一目了然、可扩展的、低耦合的判断语句喃?
那就要介绍今天的主角策略模式,可能有部分朋友对设计模式的概念很迷糊,但是不用怕,我们只是去学习设计模式的思路,具体怎么用代码去实现,那就因人而异喃,所以不用去效仿代码的书写,只用去了解策略模式思路和代码的组成部分就行
思维渐入
我们可以先不去了解什么是策略模式的理论定义,从一个小例子开始吧:
在电商项目中经常遇到这样的场景,需要通过订单的状态码 ==》订单的状态
第一种方案:通过if else的方式肯定是我们立马就能想到的思路,这种方式也是最容易理解的方式
//订单状态 1:待发货 2:已发货 3:已收货
let orderState = 1
if (orderState == 1) {
console.log("待发货")
} else if (orderState == 2) {
console.log("已发货")
} else if (orderState == 3) {
console.log("已收货")
}
第二种方案:通过策略模的方式
//算法集合 ==》 策略主体(Strategy)
let stateStrategy = {
1: () => {
console.log("待发货")
},
2: () => {
console.log("已发货")
},
3: () => {
console.log("已收货")
}
}
//持有策略主体的引用,用于选择策略主体中某个算法==》策略分配函数(Context)
function execFn(orderState){
stateStrategy[orderState]()
}
let orderState = 1
execFn(orderState)
一眼看去,哇!!明明使用策略模式的代码会变多,而且几个结构,一点都没有带来的任何优化!!没事容我慢慢道来,不要只看到策略模式的缺点,我们要学会去发现它的内部美。
-
如果现在需求改变了,需要我们添加“待退货、已退货,那么①方案就只能添加
else if判断,会破环以前的结构;然而②方案,就可以直接修改策略主体,不会影响到代码的核心逻辑,使代码更容易理解和扩展。 -
抽离出来的策略主体有很强的复用性,在封装全局方法的时候,能够一次书写多次调用。
就比如:在封装表单校验方法的时候,本质的算法就只有几个,非空、正则匹配、长度限制。只要我们抽离出这些算法就不需要重复书写了
-
当然最重要一点就是无论是代码的美观还是代码的清晰,都比多重
if else优雅许多。
策略模式的介绍
其实通过上面的代码演示,差不多可以完美的阐述策略模式了,我们再来一个的例子,你可以自己动手模仿上面的写法,完成策略主体、策略分配函数。
/**
* 用户购买商品,根据用户的会员级别,打相应的折扣,返回最后的价格
* 1 =》没有会员,不打折
* 2 =》白银会员,打9折
* 3 =》黄金会员,打8折
*/
let stateStrategy = new Map([
[1, (price) => {
return price
}],
[2, (price) => {
return price * 0.9
}],
[3, (price) => {
return price * 0.8
}]
])
function context(userType, price) {
return stateStrategy.get(userType)(price)
}
context(2, 60)
学习策略模式很简单,但是要知道那些场景可以使用确难,这要靠日常的积累,去阅读别人的代码。
当你要使用if else的时候,你就可以想一下我以后这里会扩展嘛、现在的if else数目是不是太多、现在的代码复杂程度高嘛。如果你确定符合前面任意条件,那么你都可以考虑一下策略模式。
策略模式的特点
- 策略模式只适用管理一组同类型的算法,并且这些算法是完全互斥的情况(数据平行化),也就是说任何时候,多个算法中只有一个可以生效的那一种,不适合多个判断条件关联很高的代码。
- 策略模式的关注点不是如何实现算法,而是如何组织、调用这些算法,从而让程序结构更灵活,具有更好的维护性和扩展性。
- 策略主体可以多次复用,也可以之间相互切换
使用场景比如:后端返回状态码判断、表单校验。
优点
- 符合修改封闭,运行添加的原则和单一职能原则
缺点
- 用户必须知道所有的策略类的算法,并自行决定使用哪一个算法。这就意味着用户必须理解这些算法的区别,以便适时选择恰当的算法类。
- 要定义多个对象,造成内存占用
后言
设计模式本质是在编程的时候给你思路的,不是限制你的思维创造的,只有合理运用设计模式,才能写出让人赏心悦目的代码