不写if-else可以写什么?

今天在掘金上看到一篇文章,讲的是遇到很多if-else的情况下,如何换一种思路,让代码的可读性更好。在这里整理一下从那篇文章学到的东西。

当遇到如下需求的时候:给某个班级的学生成绩进行评级,满分100分。90分以上→成绩极好;80分-90分→成绩优秀;70分-80分→成绩良好;60分-70分→成绩一般;0分-60分→成绩不及格;

按照我习惯的写法,肯定就是不假思索的用几个if-else套进去开始写(先把功能实现了再说 -_-):

// 传统的if-else写法
function scoreRating (grade) {
    let level = ''
    if (grade >= 90) {
        level = '成绩极好'
    } else if (grade >= 80) {
        level = '成绩优秀'
    } else if (grade >= 70) {
        level = '成绩良好'
    } else if (grade >= 60) {
        level = '成绩一般'
    } else {
        level = '成绩不及格'
    }
    return level
}

scoreRating(32) // 成绩不及格

这样也能运行出结果,但是缺点:

  1. 如果改需求,改变评级的文案或者是分数等级,整个的代码都需要改
  2. 这么多if-else确实有点不好看,应该有更好的写法

尝试改成下面的,配置数据和业务逻辑分开:

function scoreRating (grade) {
    let gradeLevel = [90, 80, 70, 60]
    let gradeTxt = ['成绩极好', '成绩优秀', '成绩良好', '成绩一般', '成绩不及格']

    for (let i=0, len=gradeLevel.length; i= gradeLevel[i]) {
            return gradeTxt[i]
        }
    }
    // 否则,返回‘成绩不合格’
    return gradeTxt[gradeTxt.length-1]
}

这样写的好处:

  1. 如果更改需求,只需要改gradeLevel,gradeTxt就可以了
  2. 避免修改业务逻辑,降低风险

上面的方法在课本中被称为表驱动法

在简单的情况下,逻辑语句往往更简单也更直接。但是随着逻辑链的复杂,表就变得越来越富有吸引力了。

举个例子,假设需要一个返回每个月多少天的函数,用if-else的方法:

function getMonthDays (month) {
    let day = ''
    if (month === 1) {day = 31}
    else if (month === 2) {day = 28}
    else if (month === 3) {day = 31}
    else if (month === 4) {day = 30}
    // 中间的几个月份省略
    ...
    ...
    ...
    else if (month === 12) {day = 31}
    return day
}

上面的代码显得很冗余,换成表驱动法,就可以这样:

function getMonthDays(month) {
    // 这两行代码只是简单的表达意思...
    let day = [31,28,31,30,31,30,31,31,30,31,30,31]
    return day[month-1]
}

这样看起来清爽很多。

在这里通过上面的简单例子,引出表驱动法。
表驱动法的意义在于:逻辑和数据分离。因为在程序中,修改数据和修改逻辑的方法是不同的,成本也不同。数据的添加是相对简单低风险的,但是增加或修改逻辑的风险和成本是很高的。

最后:
在工作中在合适的场景,可以考虑用表驱动法改写冗余的if-else

参考链接
特定场景下取代if-else和switch的方案
百度百科—表驱动法
这个例子中的if else也要重构掉吗?

你可能感兴趣的:(不写if-else可以写什么?)