【面试题】什么是策略模式?用了策略模式之后,再也不用写那么多 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前端面试题库

目录
打赏
0
0
0
0
12
分享
相关文章
设计模式最佳套路5 —— 愉快地使用工厂方法模式
工厂模式一般配合策略模式一起使用,当系统中有多种产品(策略),且每种产品有多个实例时,此时适合使用工厂模式:每种产品对应的工厂提供该产品不同实例的创建功能,从而避免调用方和产品创建逻辑的耦合,完美符合迪米特法则(最少知道原则)。
108 6
【面试题】如何理解 前端设计模式-测策略模式?
【面试题】如何理解 前端设计模式-测策略模式?
CRUD很无聊?一起学设计模式吧!--策略模式
CRUD很无聊?一起学设计模式吧!--策略模式
113 0
Zp
初尝策略模式~真香
初尝策略模式~真香
Zp
153 0
面试题(二十五)设计模式
1. 设计模式 1.1 说一说设计模式的六大原则 参考答案 单一职责原则 一个类,应当只有一个引起它变化的原因;即一个类应该只有一个职责。 就一个类而言,应该只专注于做一件事和仅有一个引起变化的原因,这就是所谓的单一职责原则。该原则提出了对对象职责的一种理想期望,对象不应该承担太多职责,正如人不应该一心分为二用。唯有专注,才能保证对象的高内聚;唯有单一,才能保证对象的细粒度。对象的高内聚与细粒度有利于对象的重用。一个庞大的对象承担了太多的职责,当客户端需要该对象的某一个职责时,就不得不将所有的职责都包含进来,从而造成冗余代码。 里氏替换原则 在面向对象的语言中,继承是必不可少的、优秀的语言机制
122 0
面试官:谈谈简单工厂模式和策略模式的区别?我居然答不上来。。
面试官:谈谈简单工厂模式和策略模式的区别?我居然答不上来。。
162 0
面试官:谈谈简单工厂模式和策略模式的区别?我居然答不上来。。
阿里面试官:使用策略模式+工厂模式干掉代码中过多的if-else
过多if-else项目背景 如果一开始就知道现在的业务需要,大部分人都不会在代码里添加过多的if-else判断的,烂代码基本都是刚开始写代码时并没有太多的需求,随着期需求不断的修改增加,开发时间也较的紧张,代码往往都是怎么快速怎么写。当然多写一个if-else比使用各种设计模式肯定来的更快速了,这也就导致项目代码慢慢变得臃肿,难以维护的主要原因。在有空闲时间的情况下就可以给以前的代码做一次手术了。先看本次未优化前的代码:
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等