首页/开发/代码质量与评审速查/手法:Replace Nested Conditional with Guard Clauses(卫语句)
重构手法62 条

手法:Replace Nested Conditional with Guard Clauses(卫语句)

嵌套 if 的深层分支改为前置守卫:先处理异常与边界并提前返回,主流程保持在同一层缩进;深层嵌套常意味着条件被反向表达。

卫语句是什么

用卫语句替换嵌套条件:把异常、边界与不合法输入在函数开头处理掉并提前返回,让主流程保持在同一层缩进。深层嵌套往往意味着条件被反向表达——把必须成立的前提先写清楚,主逻辑自然浮到表面。

基本信息

适用场景条件深层嵌套,主逻辑被边界推向内部
写法异常与边界条件提前返回或抛出
收益主流程平铺,缩进层级减少
语言差异返回多值用元组,单一出口风格可与卫语句共存
前提提前返回不改变原有副作用顺序

典型使用场景

  • 参数校验先做,主体逻辑不再包在判断里
  • 资源或状态未就绪时提前返回,避免层层包裹
  • 权限不足直接拒绝,后续代码不必再判断
  • 循环里跳过不满足条件的元素,减少嵌套
  • 值对象构造时先把非法输入挡在门外

替换前后

替换前后
// 之前:两层嵌套,主逻辑被挤到最里面
if (isSeparated) {
    if (isRetired) result = 0; else result = amount;
} else {
    if (isRetired) result = amount * 0.9; else result = amount * 0.8;
}

// 之后:先处理边界,主流程平铺
if (isSeparated) return isRetired ? 0 : amount;
return isRetired ? retiredAmount() : normalAmount();

两种风格对照

情形推荐理由
边界与异常较多卫语句边界先出局,主流程更短
副作用需统一收尾卫语句加尾部处理中途返回会跳过收尾逻辑
需要返回多个值元组或结果对象单一返回点便于统一构造
单一出口并非必须:当收尾逻辑需要集中时,可以让放行路径统一在函数尾部;否则提前返回通常更容易读。
卫语句里做副作用(日志、计数、埋点)会让重构悄悄改变行为:搬动位置前先确认原有调用顺序是否被依赖。
另一种常见写法是先把不合法输入转成明确的错误结果再返回,调用方按结果分支处理:既不抛异常,也避免把校验逻辑散落在主干里。

易错点

  • 所有分支都改成提前返回:正常路径与异常路径语义被混淆,读者分不清主流程
  • 卫语句里加入日志或计数:行为在重构中变化,指标出现无解释的波动
  • 提前返回跳过收尾逻辑:资源释放或状态写入被漏掉,出现泄漏或状态不一致
  • 只调缩进不调条件表达:条件仍然是反向的,可读性没有真正改善

数据来源与参考

  • 《重构》第 2 版 · 第 10 章(Replace Nested Conditional with Guard Clauses)
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌