重构手法——函数行为重塑类 | 语意 | 用卫语句替换嵌套条件

55 阅读2分钟

简介

"用保护子句替换嵌套条件语句"是改善代码可读性的有效重构手法。通过将深层嵌套的条件判断转换为提前返回的守卫语句,可以显著降低代码复杂度,使主逻辑更加清晰。

针对的症状(代码坏味道)

  • 超过2层的条件嵌套
  • 主逻辑被包裹在多级条件中
  • 存在大量else-if链式结构
  • 条件分支权重相同但层级不同

用保护子句替换嵌套条件的详细步骤

  1. 识别嵌套入口
    • 查找最外层条件判断
    • 确定条件失败时的处理方式
  2. 反转条件逻辑
    • 将条件表达式取反
    • 处理反向逻辑结果
  3. 提前返回/抛出
    • 用return/throw终止异常分支
    • 减少主逻辑缩进层级
  4. 重复应用
    • 逐层处理每个嵌套条件
    • 保持主逻辑线性化

示例

重构前代码:

double getPayAmount(Employee employee) {
    double result;
    if (employee.isSeparated()) {
        result = 0;
    } else {
        if (employee.isRetired()) {
            result = retiredAmount();
        } else {
            result = normalPayAmount();
            if (result < 0) {
                result = 0;
            }
        }
    }
    return result;
}

重构步骤:

  1. 处理最外层条件:

    double getPayAmount(Employee employee) {
        if (employee.isSeparated()) {
            return 0;
        }
    
        // ...剩余逻辑...
    }
    
  2. 处理第二层条件:

    double getPayAmount(Employee employee) {
        if (employee.isSeparated()) return 0;
        if (employee.isRetired()) return retiredAmount();
    
        // ...剩余逻辑...
    }
    
  3. 最终重构结果:

    double getPayAmount(Employee employee) {
        if (employee.isSeparated()) return 0;
        if (employee.isRetired()) return retiredAmount();
    
        double result = normalPayAmount();
        return Math.max(result, 0);
    }
    

练习

基础练习题

  1. 简单嵌套条件解构

    // 重构前
    String getGrade(int score) {
        if (score >= 0) {
            if (score >= 60) {
                if (score >= 80) {
                    return "A";
                } else {
                    return "B";
                }
            } else {
                return "C";
            }
        }
        return "Invalid";
    }
    

进阶练习题

  1. 复合条件保护

    // 重构前
    void processOrder(Order order) {
        if (order != null) {
            if (order.isValid()) {
                if (order.getItems().size() > 0) {
                    // 主处理逻辑
                } else {
                    log.error("Empty order");
                }
            } else {
                log.error("Invalid order");
            }
        } else {
            log.error("Null order");
        }
    }
    

综合拓展练习题

  1. 多层异常处理

    // 重构前
    FileInputStream openFile(String path) {
        try {
            File file = new File(path);
            if (file.exists()) {
                if (file.canRead()) {
                    return new FileInputStream(file);
                } else {
                    throw new IOException("No read permission");
                }
            } else {
                throw new FileNotFoundException();
            }
        } catch (Exception e) {
            // 统一处理
        }
    }
    

代码审查要点

  1. 优点:

    • 减少代码缩进层级
    • 提前暴露错误条件
    • 主逻辑更加聚焦
  2. 潜在问题:

    • 避免过度使用return语句
    • 保持条件判断的原子性
    • 注意资源清理顺序