重构手法——函数行为重塑类 | 语意 | 拆分阶段

50 阅读2分钟

简介

"拆分阶段"是解耦复杂流程的核心重构手法。通过将混合处理逻辑分解为顺序执行的独立阶段,可以提升代码的可维护性、可测试性和可扩展性。

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

  • 单个方法/类承担多个处理阶段
  • 难以单独测试某个处理环节
  • 存在混杂的中间状态变量
  • 需要调整处理流程顺序

拆分阶段的详细步骤

  1. 识别处理阶段
    • 分析代码中的逻辑边界
    • 标记输入输出数据格式
  2. 创建中间数据结构
    • 定义阶段间的数据传递格式
    • 封装原始数据处理结果
  3. 提取独立处理阶段
    • 为每个阶段创建独立方法/类
    • 通过中间数据传递结果
  4. 重构调用流程
    • 组合阶段形成完整流程
    • 消除全局状态依赖

示例

重构前代码:

void processOrder(String input) {
    // 解析阶段
    String[] parts = input.split(",");
    String productId = parts[0];
    int quantity = Integer.parseInt(parts[1]);

    // 计算阶段
    double price = getPrice(productId);
    double total = price * quantity;

    // 输出阶段
    System.out.println("Total: " + total);
}

重构步骤:

  1. 创建中间数据结构:

    class OrderData {
        String productId;
        int quantity;
        double price;
    }
    
  2. 最终重构结果:

    void processOrder(String input) {
        OrderData data = parseInput(input);
        calculateTotal(data);
        outputResult(data);
    }
    
    OrderData parseInput(String input) {
        String[] parts = input.split(",");
        OrderData data = new OrderData();
        data.productId = parts[0];
        data.quantity = Integer.parseInt(parts[1]);
        return data;
    }
    
    void calculateTotal(OrderData data) {
        data.price = getPrice(data.productId);
        data.total = data.price * data.quantity;
    }
    
    void outputResult(OrderData data) {
        System.out.println("Total: " + data.total);
    }
    

练习

基础练习题

  1. 简单流程拆分

    // 重构前
    void handleUser(String json) {
        User user = parseJson(json);
        sendWelcomeEmail(user.email);
    }
    

进阶练习题

  1. 电商订单处理

    // 重构前
    void processPayment(String transaction) {
       String[] details = transaction.split("\\|");
       double amount = Double.parseDouble(details[1]);
       boolean isValid = validateCard(details[0]);
    
       if (isValid) {
          chargeCard(amount);
          updateInventory(details[2]);
       }
    }
    

综合拓展练习题

  1. 数据分析管道

    // 重构前
    void analyzeLogs(List<String> logs) {
       Map<String, Integer> counts = new HashMap<>();
       for (String log : logs) {
          String[] parts = log.split(" ");
          String ip = parts[0];
          counts.put(ip, counts.getOrDefault(ip, 0) + 1);
       }
    
       List<Map.Entry<String, Integer>> sorted = new ArrayList<>(counts.entrySet());
       sorted.sort((a, b) -> b.getValue().compareTo(a.getValue()));
    
       for (int i = 0; i < Math.min(10, sorted.size()); i++) {
          System.out.println(sorted.get(i));
       }
    }
    

代码审查要点

  1. 优点:

    • 明确阶段职责边界
    • 支持阶段独立优化
    • 增强代码可测试性
  2. 潜在问题:

    • 控制中间数据规模
    • 注意阶段执行顺序
    • 避免过度拆分