记录一次 if-else 代码优化的完整过程

职场   2024-10-08 11:27   福建  
让我们来探讨一下如何将出租车叫车应用中的司机分配逻辑,从复杂的嵌套 if 语句中简化,使之更加清晰和易于维护。
在之前的项目中,我参与了一款至今仍被广泛使用的出租车叫车应用的开发,虽然我不清楚他们现在使用的代码细节,但当时我们处理司机分配的代码大致是这样的:

异步函数 assignDriver 用来为乘客分配司机,它接收乘客信息和可用司机列表作为参数。

函数先计算每个司机到乘客的距离,然后遍历所有可用司机,检查以下条件:

  • 司机是否在 5 公里以内。

  • 如果乘客有偏好的车型,那么司机的车型必须符合偏好。

  • 司机的评分至少要 4.5 分,如果有高级司机偏好,还要确保司机是高级司机。

  • 如果没有找到满足 4.5 分要求的司机,则接受评分为 4.0 分及以上的司机。

这个过程用了五层嵌套的 if 语句,虽然看起来不糟糕,但可以想象,如果再增加一些其他条件(比如高峰期加价、忠诚度计划等),代码会变得多么复杂。


解决问题

幸运的是,有一些方法可以把这些嵌套的逻辑"拍平",甚至最终可以做到不需要任何 if 语句,我们来看看如何重构这段代码。

1、卫语句(Guard Clauses)

卫子句(Guard Clauses)是一种编程技巧,用于在函数或方法的执行过程中尽早地检查错误条件或异常情况,并在满足这些条件时立即退出函数。

卫子句是一种有效的代码设计模式,有助于编写更加健壮和易于理解的代码。

def divide(a, b):    if b == 0:        raise ValueError("Cannot divide by zero")    return a / b

这个例子中,如果除数 为 0,函数会立即抛出一个 ValueError 异常。

我们可以利用卫子句,把最外层的 if 条件拿出来,直接跳过不符合条件的司机,减少嵌套。

下面是修改后的代码:

通过使用卫语句,我们减少了两层嵌套,让代码变得稍微清晰一点。

2、决策表(Decision Tables)

决策表是一种数据结构,用于以表格的形式表示复杂的逻辑决策,使得逻辑决策更加清晰和易于理解。

决策通常用于替代复杂的条件语句(如if-else嵌套),特别是在逻辑判断较多且条件复杂的情况下。

在编程中,决策表可以通过多种方式实现,例如使用查找表、状态机或专门的决策表库。

以下是使用 Python 实现的一个简单示例:

def evaluate_decision_table(table, context):    for rule in table:        if all(context.get(k) == v for k, v in rule['conditions'].items()):            return rule['action']    return None# 定义决策表decision_table = [    {        'conditions': {'age': 18, 'has_license': True},        'action': 'Drive'    },    {        'conditions': {'age': 18, 'has_license': False},        'action': 'Learn to drive'    },    {        'conditions': {'age': 17, 'has_license': True},        'action': 'Cannot drive'    }]# 上下文context = {'age': 18, 'has_license': True}# 评估决策表action = evaluate_decision_table(decision_table, context)print(action)  # 输出: Drive

在这个例子中,决策表定义了几条规则,每条规则包含条件和动作。evaluate_decision_table 函数遍历决策表,检查每条规则的条件是否满足,并执行相应的动作。

接下来,我们可以把 if-else 逻辑提取到独立的函数中,构建一个"决策表",这个表格的条目按照特定的顺序排列,从最严格的条件开始,逐个检查司机是否符合条件。

通过决策表,我们完全消除了嵌套的 if 语句,司机分配的逻辑也变得更加灵活,只需要修改条件数组即可。

3、函数组合(Function Composition)

函数组合是一种编程技巧,它允许你将多个函数组合起来,创建一个执行多个函数操作的新函数。

在不同的编程语言中,函数组合可以通过多种方式实现,如直接调用、使用高阶函数、使用函数式编程库等。

函数组合是一种强大的编程模式,可以帮助开发者以更简洁、更模块化的方式构建复杂的逻辑。

Python 示例:

def add(x, y):    return x + ydef multiply(x, y):    return x * ydef add_and_multiply(x, y, z):    return multiply(add(x, y), z)result = add_and_multiply(1, 2, 3)  # 输出: 18

在这个例子中,add_and_multiply 函数组合了 add 和 multiply 两个函数。

JavaScript 示例(使用高阶函数):

const add = (x, y) => x + y;const multiply = (x, y) => x * y;const addAndMultiply = (x, y, z) => multiply(add(x, y), z);const result = addAndMultiply(1, 2, 3);  // 输出: 9

最后一步,我们可以通过把 for 循环转换成 Array.find() 方法,并为每个 if 条件创建单独的函数,彻底消除代码中的 if 语句。

通过使用函数式编程的一些基本技巧,我们优化了以下内容:

  • 移除了所有的嵌套 if 语句;

  • 解耦了大部分逻辑,使其更容易修改;

  • 通过将每个 if-else 块放入单独的函数中,使代码更易于理解;

  • 最后,顺便让代码量减少了约三分之一。

参考链接:https://lackofimagination.org/2024/09/avoiding-if-else-hell-the-functional-style/

菜鸟教程
学的不仅是技术,更是梦想!
 最新文章