【策略模式】让 if else 更优雅

473 阅读4分钟

这是我参与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数目是不是太多、现在的代码复杂程度高嘛。如果你确定符合前面任意条件,那么你都可以考虑一下策略模式。

策略模式的特点

  • 策略模式只适用管理一组同类型的算法,并且这些算法是完全互斥的情况(数据平行化),也就是说任何时候,多个算法中只有一个可以生效的那一种,不适合多个判断条件关联很高的代码。
  • 策略模式的关注点不是如何实现算法,而是如何组织、调用这些算法,从而让程序结构更灵活,具有更好的维护性和扩展性。
  • 策略主体可以多次复用,也可以之间相互切换

使用场景比如:后端返回状态码判断、表单校验。

优点
  • 符合修改封闭,运行添加的原则和单一职能原则
缺点
  • 用户必须知道所有的策略类的算法,并自行决定使用哪一个算法。这就意味着用户必须理解这些算法的区别,以便适时选择恰当的算法类。
  • 要定义多个对象,造成内存占用

后言

设计模式本质是在编程的时候给你思路的,不是限制你的思维创造的,只有合理运用设计模式,才能写出让人赏心悦目的代码