简化条件逻辑 旨在解决复杂的条件逻辑带来的代码复杂度、可读性差以及难以维护的问题。
复杂的条件逻辑是导致程序复杂度上升的常见原因之一。通过运用这些技巧,开发者可以使代码更清晰地表达意图,区分正常行为与异常情况,并消除重复的分支逻辑。
以下是本章所有重构技巧的整理、类型和说明:
技巧(中文/英文)
核心目标与动机
做法概要
示例说明
分解条件表达式 (Decompose Conditional)
复杂的条件逻辑会使代码的可读性大大降低。将条件判断和每个条件分支分解成独立的函数,并根据其用途命名,可以更清楚地表达意图,并突出每个分支的原因。
对条件判断和每个条件分支分别运用 提炼函数 手法。
将计算价格的 if/else 结构(判断是否在夏季),拆分为 summer()(判断条件)和 summerCharge() / regularCharge()(执行分支)三个命名良好的函数。
合并条件表达式 (Consolidate Conditional Expression)
当多个条件检查结果相同,且它们共同构成一个逻辑检查时,应将其合并为单个表达式。这有助于表述“实际上只有一次条件检查”,使检查意图更清晰,并为后续使用 提炼函数 做准备。
确保条件表达式都没有副作用。使用逻辑或或逻辑与将相关条件表达式合并。
ㅤ
以卫语句取代嵌套条件表达式 (Replace Nested Conditional with Guard Clauses)
区分正常行为(函数核心逻辑)和异常/罕见情况(提前退出)。卫语句(Guard Clauses)给异常分支以特别的重视,使其不必深嵌于主逻辑中,从而避免嵌套条件逻辑导致的混乱。
识别异常条件,使用卫语句 if (condition) return; 立即返回或抛出错误。如果条件反转能使卫语句更容易表达,则先反转条件。
在计算工资的函数中,如果员工“已离职”或“已退休”,应使用卫语句提前返回 0 或包含原因码的结果,而不是将核心计算逻辑层层嵌套在 else 块中。
以多态取代条件表达式 (Replace Conditional with Polymorphism)
当有多个函数基于 同一套类型代码 进行分支选择时,应使用继承和多态来取代重复的 switch 或连续 if/else 逻辑。这有助于避免“重复的 switch”坏味道。
针对条件逻辑的每种分支创建一个子类,将各自的逻辑搬移到子类中,并使用工厂函数返回恰当的对象实例。
在处理不同类型鸟类的行为(如 airSpeedVelocity 和 plumage)时,针对每种鸟类(如 EuropeanSwallow、AfricanSwallow)创建一个子类,将类型判断逻辑转移到多态方法中。
引入特例 (Introduce Special Case)
消除代码库中多处存在的对 特殊值(如 null 或 “unknown”)的重复检查和处理逻辑。特例对象(Special Case Object)将这些共用处理逻辑集中到一处。
创建一个特例对象(或字面量记录)来代表特殊情况。使用函数组合成类或函数组合成变换将共用行为搬移到特例对象中。
将对 “未知顾客” (aCustomer === "unknown") 的检查,替换为一个 UnknownCustomer 特例对象,该对象封装了所有针对未知顾客的默认行为(如返回 "occupant" 作为名字、默认计价套餐)。
引入断言 (Introduce Assertion)
明确标明代码运行所依赖的 假设条件,从而使程序在执行到某一点时,明确告知阅读者其对当前状态做了何种假设。
加入一个条件表达式,它应总是为真。如果断言失败,则表示程序员犯了错误。
在计算折扣的函数中,如果假设折扣率 discountRate 永远是正数,则应加入断言 assert(this.discountRate >= 0) 来明确标示这个假设。
重构的关键在于运用这些技巧来简化代码的 可读性 和 可维护性。 例如,分解条件表达式 使得复杂的判断逻辑有了命名良好的解释,而 以卫语句取代嵌套条件表达式 则清晰地分离了主要流程和异常处理,使读者能更快聚焦于函数的目的。 以多态取代条件表达式 尤其重要,它解决了面向对象设计中由于过度依赖类型码和重复分支逻辑造成的耦合问题。
💡
简化条件逻辑就像是在整理一张复杂的路线图。分解条件表达式是将复杂的判断逻辑(如“夏季折扣”)赋予清晰的名称,使地图上的标记一目了然。卫语句是处理死胡同或禁行区域(异常情况),确保我们能快速排除非主干道,保持注意力集中在主要路径上。而使用多态取代条件表达式,则是将那些重复、基于类型的收费站(分支逻辑)整合到一个智能导航系统(继承体系)中,这样当你需要增加一个新的目的地类型时,只需更新导航系统,而不需要修改沿途的每一个收费站。
学习笔记——《重构改善现有代码2》:重构API学习笔记——《重构改善现有代码2》:重新组织数据