用了策略模式之后,再也不用写那么多 if else 了,真香!

前言

从我个人理解来看,设计模式其实就藏在我们平时的代码中,只是有人把它们提、炼出来,赋予了一些专业的名词和定义,下面给大家介绍一个日常项目开发中非常实用的设计模式,也就是策略模式

策略模式的定义

先来看下策略模式的定义:定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换。

简单来说就是有多种选择,然后一般只会选择一种。从代码的角度来说就是,定义一系列的ifelseif,然后只会命中其中一个。

举个例子

话不多说,直接来看例子,比如我们需要计算员工工资,员工工资计算规则如下:

  • 高级工:时薪为25块/小时
  • 中级工:时薪为20块/小时
  • 初级工:时薪为15块/小时

按每天10小时的工作时长来算。

一、第一版实现:

js 复制代码
const calculateSalary = function (workerLevel, workHours = 10) {
    if (workerLevel === 'high') {
        return workHours * 25
    }
    if (workerLevel === 'middle') {
        return workHours * 20
    }
    if (workerLevel === 'low') {
        return workHours * 15
    }
}
console.log(calculateSalary('high')) // 250
console.log(calculateSalary('middle')) // 200

这段代码具有明显的缺点:

  • calculateSalary函数庞大,有许多的if else语句,这些语言需要覆盖所有的逻辑分支
  • calculateSalary函数缺乏弹性,如果新增一种员工等级higher,需要修改calculateSalary函数的内部实现,违反开放------封闭原则
  • 算法的复用性差

二、第二版实现(函数组合):

当然,我们可以使用函数组合的方式重构代码,把每一个if中的逻辑单独抽离成一个函数。

js 复制代码
const workerLevelHigh = function (workHours) {
    return workHours * 25
}

const workerLevelMiddle = function (workHours) {
    return workHours * 20
}
const workerLevelLow = function (workHours) {
    return workHours * 15
}

const calculateSalary = function (workerLevel, workHours = 10) {
    if (workerLevel === 'high') {
        return workerLevelHigh(workHours)
    }
    if (workerLevel === 'middle') {
        return workerLevelMiddle(workHours)
    }
    if (workerLevel === 'low') {
        return workerLevelLow(workHours)
    }
}
console.log(calculateSalary('high', 10)) // 250
console.log(calculateSalary('middle', 10)) // 200

这样会提高算法的复用性,但这种改善十分有限,calculateSalary函数依旧庞大和缺乏弹性。

三、第三版实现(策略模式):

我们可以把不变的部分和变化的部分拆分开来。

  • 不变的部分:算法的使用方式不变,都是根据某个算法取得计算后的工资数额;
  • 变化的部分:算法的实现。

我们js的对象是key value的形式,这可以帮助我们天然的替换掉if else

因此,我们可以定义对象的两部分:

  • 针对变化的部分,我们可以定义一个策略对象,它封装了具体的算法,负责具体的计算过程
  • 针对不变的部分,我们提供一个Context函数,它接受客户的请求,随后把请求委托给策略对象。
js 复制代码
const strategies = {
    "high": function (workHours) {
        return workHours * 25
    },
    "middle": function (workHours) {
        return workHours * 20
    },
    "low": function (workHours) {
        return workHours * 15
    },
}

const calculateSalary = function (workerLevel, workHours) {
    return strategies[workerLevel](workHours)
}
console.log(calculateSalary('high', 10)) // 250
console.log(calculateSalary('middle', 10)) // 200

策略模式的优缺点

从我个人在实际项目中的使用来看,策略模式的优缺点如下:

优点:

  • 代码复杂度降低 :再也不用写那么多if else了。eslint其中有一项规则配置叫圈复杂度,其中一条分支也就是一个if会让圈复杂增加1,圈复杂度高的代码不易阅读和维护,用策略模式就能很好的解决这个问题;
  • 易于切换、理解和扩展 :它将算法封装在独立的strategy中,比如你要在上面代码中加一个等级higherlower,直接更改策略对象strategies就行,十分方便。
  • 复用性高 :策略模式中的算法可以复用在系统的其它地方,你只需要用将策略类strategies用export或者module.exports导出,就能在其他地方很方便的复用。

缺点:

  • 增加使用者使用负担 :因为大量运用策略模式会在实际项目中堆砌很多策略类或者策略对象,这样项目的新人如果不熟悉这些策略类和策略对象,会增加他们的使用成本和学习成本,前期来说会比看if else更加难懂。

小结

以上就是我个人对策略模式的解读和了解啦,实际上项目中用策略模式的场景还是挺多的,因为在写业务代码中,很容易写出大量的if else,这时候就可以封装为策略模式,方便项目维护和扩展,从我个人的使用体验来看,还是相当香的。

大家喜欢在实际项目使用策略模式么,欢迎留言和讨论~

相关推荐
ByteCraze3 分钟前
前端性能与监控指标采集系统设计方案
前端
山楂树の8 分钟前
前端实时渲染性能优化 使用cocoRLE编码进行图像传输并着色绘制
前端·图像处理·实时互动
程序员祥云10 分钟前
云希谷技术面
前端
一 乐16 分钟前
心理健康管理|基于springboot + vue心理健康管理系统(源码+数据库+文档)
java·开发语言·前端·数据库·vue.js·spring boot·后端
G***E31617 分钟前
重塑前端的力量:从界面承载到体验驱动的全链路能力进化
前端
HIT_Weston17 分钟前
60、【Ubuntu】【Gitlab】拉出内网 Web 服务:Gitlab 配置审视(四)
前端·ubuntu·gitlab
G***E31618 分钟前
前端技术的下一场深变:从工程化到智能化的全面升级
前端
前端小端长18 分钟前
深入理解Composition API与Vue3.0响应式原理
开发语言·javascript
哆啦A梦15889 小时前
商城后台管理系统 03 登录布局
javascript·vue.js·elementui
曼巴UE59 小时前
UE FString, FName ,FText 三者转换,再次学习,官方文档理解
服务器·前端·javascript