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

admin3个月前 (10-09)未分类217

让我们来探讨一下如何将出租车叫车应用中的司机分配逻辑,从复杂的嵌套 if 语句中简化,使之更加清晰和易于维护。

在之前的项目中,我参与了一款至今仍被广泛使用的出租车叫车应用的开发,虽然我不清楚他们现在使用的代码细节,但当时我们处理司机分配的代码大致是这样的:



IMG_4692.png


异步函数 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

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

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

下面是修改后的代码:



IMG_4693.png

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

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 逻辑提取到独立的函数中,构建一个"决策表",这个表格的条目按照特定的顺序排列,从最严格的条件开始,逐个检查司机是否符合条件。



IMG_4694.png

通过决策表,我们完全消除了嵌套的 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 语句。

IMG_4695.png

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

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

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

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

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



相关文章

基于UniAPP开发的微信小程序

基于UniAPP开发的微信小程序

写在前面非常感谢您对本系统的关注!我们非常激动地宣布,我们正式推出全新的版本。如果您想获取更多关于这个令人兴奋的信息的详细信息,请关注我们!了解更多关于如何成为本系统授权的信息。不要错过这个机会,立即...

微信小程序上拉加载、下拉刷新的使用方法

微信小程序上拉加载、下拉刷新的使用方法

一、定义数据data() {return {list: [],      //数据列表noMore: ...

如何用PHP模拟登录并抓取数据 ?

如何用PHP模拟登录并抓取数据 ?

使用PHP的Curl扩展库可以模拟实现登录,并抓取一些需要用户账号登录以后才能查看的数据。具体实现的流程如下1. 首先需要对相应的登录页面的html源代码进行分析,获得一些必要的信息:1)登录页面的地...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。