【面试题】什么是策略模式?用了策略模式之后,再也不用写那么多 if else 了,真香!

简介: 【面试题】什么是策略模式?用了策略模式之后,再也不用写那么多 if else 了,真香!

给大家推荐一个实用面试题库

1、前端面试题库 (面试必备)            推荐:★★★★★

地址:web前端面试题库

前言

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

策略模式的定义

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

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

举个例子

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

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

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

一、第一版实现:

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中的逻辑单独抽离成一个函数。

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函数,它接受客户的请求,随后把请求委托给策略对象。
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,这时候就可以封装为策略模式,方便项目维护和扩展,从我个人的使用体验来看,还是相当香的。

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

给大家推荐一个实用面试题库

1、前端面试题库 (面试必备)            推荐:★★★★★

地址:web前端面试题库

相关文章
|
6天前
|
设计模式 算法
【设计模式】阿里终面:你觉得这个例子是策略模式吗?
【设计模式】阿里终面:你觉得这个例子是策略模式吗?
9 1
|
7月前
|
设计模式 JavaScript 前端开发
超级简单的设计模式,看不懂你来打我
超级简单的设计模式,看不懂你来打我
|
11月前
|
设计模式 安全 调度
设计模式——单例模式(面试手撕顶呱呱)
设计模式——单例模式(面试手撕顶呱呱)
|
11月前
|
设计模式 算法 uml
CRUD很无聊?一起学设计模式吧!--策略模式
CRUD很无聊?一起学设计模式吧!--策略模式
75 0
|
设计模式 存储 缓存
阿里面试官:使用策略模式+工厂模式干掉代码中过多的if-else
过多if-else项目背景 如果一开始就知道现在的业务需要,大部分人都不会在代码里添加过多的if-else判断的,烂代码基本都是刚开始写代码时并没有太多的需求,随着期需求不断的修改增加,开发时间也较的紧张,代码往往都是怎么快速怎么写。当然多写一个if-else比使用各种设计模式肯定来的更快速了,这也就导致项目代码慢慢变得臃肿,难以维护的主要原因。在有空闲时间的情况下就可以给以前的代码做一次手术了。先看本次未优化前的代码:
|
设计模式 uml 微服务
面试官:谈谈简单工厂模式和策略模式的区别?我居然答不上来。。
面试官:谈谈简单工厂模式和策略模式的区别?我居然答不上来。。
106 0
面试官:谈谈简单工厂模式和策略模式的区别?我居然答不上来。。
|
设计模式 关系型数据库 MySQL
平时代码中用不到设计模式?Are you kidding me?
引子 平时我是个反应非常慢的人。有多慢呢?大概是两年前有次团队内部开会时,我听到同学说平时代码中用不到设计模式,我当时没有回答。两年后我终于反应过来了:“Are you kidding me?我每天都在用!”
平时代码中用不到设计模式?Are you kidding me?
|
设计模式 SQL 前端开发
面试官问,你在开发中有用过什么设计模式吗?我懵了
面试官问,你在开发中有用过什么设计模式吗?我懵了
262 0
面试官问,你在开发中有用过什么设计模式吗?我懵了
|
设计模式 存储 算法
再一次实战策略模式,太好用了
再一次实战策略模式,太好用了
146 0
再一次实战策略模式,太好用了