重构手法——函数行为重塑类 | 语意 | 用测试替换异常

46 阅读2分钟

简介

"用测试替换异常"是一种预防性编程的重构手法。通过预先执行状态检查来避免异常发生,将异常处理逻辑转换为正常的条件分支,提高代码可预测性和执行效率。

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

  • 使用异常处理预期内的常规错误
  • 频繁捕获可预见的异常类型
  • 异常处理掩盖业务逻辑缺陷

用测试替换异常的详细步骤

  1. 识别异常捕获点
    • 查找try-catch中的常规业务错误处理
    • 确定可预测的错误触发条件
  2. 创建状态检查方法
    • 将异常触发条件转换为布尔测试方法
    • 确保检查方法的幂等性
  3. 重构处理逻辑
    • 用if-check替换try-catch结构
    • 将catch块转换为else分支
  4. 清理残留结构
    • 移除不再需要的异常声明
    • 简化方法返回类型

示例

重构前代码:

class CollectionUtils {
    String getFirstElement(List<String> list) {
        try {
            return list.get(0);
        } catch (IndexOutOfBoundsException e) {
            return null;
        }
    }
}

重构步骤:

  1. 创建空集合检查方法:

    private boolean isEmpty(List<String> list) {
        return list == null || list.isEmpty();
    }
    
  2. 重构获取逻辑:

    class CollectionUtils {
        String getFirstElement(List<String> list) {
            if (isEmpty(list)) {
                return null;
            }
            return list.get(0);
        }
    }
    

练习

基础练习题

  1. 空指针防御改造

    // 重构前
    class StringParser {
        int parse(String value) {
            try {
                return Integer.parseInt(value);
            } catch (NumberFormatException e) {
                return -1;
            }
        }
    }
    

进阶练习题

  1. 复合状态测试

    // 重构前
    class DatabaseAccessor {
        Connection getConnection(String config) {
            try {
                return DriverManager.getConnection(config);
            } catch (SQLException e) {
                throw new RuntimeError("Connection failed");
            }
        }
    }
    

综合拓展练习题

  1. 复杂业务状态验证

    // 重构前
    class PaymentProcessor {
        void process(Order order) {
            try {
                validateOrder(order);
                chargeCustomer(order);
            } catch (PaymentException e) {
                handleFailure(order, e);
            }
        }
    }
    

代码审查要点

  1. 优点:

    • 提高代码执行效率
    • 明确业务约束条件
    • 增强代码可测试性
  2. 潜在问题:

    • 保证检查方法与业务操作的原子性
    • 避免重复状态检查
    • 正确处理竞态条件