重构手法——数据重组类 | 数据完整性操作 | 保留整个对象

98 阅读2分钟

简介

"保留整个对象"(Preserve Whole Object)重构手法通过传递完整对象替代多个单独参数,解决数据泥团(Data Clumps)问题。当方法需要从同一对象获取多个属性时,直接传递该对象可提高代码内聚性。

典型代码坏味道

  • 方法参数列表包含多个来自同一对象的属性
  • 重复的对象属性获取操作
  • 频繁的对象解构操作

重构步骤

  1. 识别参数关联

    • 找到参数列表中来自同一对象的属性组
    • 确认这些属性在方法中的使用方式
    • 检查对象是否包含完整上下文信息
  2. 重构方法签名

    • 用对象参数替换多个独立属性
    • 保持原始方法作为兼容层(可选)
    • 更新方法内部访问方式
  3. 更新调用链

    • 修改所有调用点传递完整对象
    • 处理多层嵌套调用中的参数传递
    • 移除不必要的属性获取代码
  4. 验证与测试

    • 确保对象在调用链中的可用性
    • 验证null对象处理逻辑
    • 检查继承体系中的方法覆盖

示例

原始代码:

public class Room {
    public boolean withinPlan(HeatingPlan plan) {
        int low = daysTempRange().getLow();
        int high = daysTempRange().getHigh();
        return plan.withinRange(low, high);
    }
}

class HeatingPlan {
    public boolean withinRange(int low, int high) {
        return low >= _range.getLow() && high <= _range.getHigh();
    }
}

重构后的代码:

public class Room {
    public boolean withinPlan(HeatingPlan plan) {
        return plan.withinRange(daysTempRange());
    }
}

class HeatingPlan {
    public boolean withinRange(TempRange roomRange) {
        return roomRange.getLow() >= _range.getLow()
                && roomRange.getHigh() <= _range.getHigh();
    }
}

专项练习

基础练习

  1. 用户信息参数重构

    public class UserService {
        public void sendWelcomeEmail(String firstName, String email, LocalDate joinDate) {
            // 发送欢迎邮件逻辑...
        }
    
        // 调用方式:sendWelcomeEmail(user.getFirstName(), user.getEmail(), user.getJoinDate());
    }
    

进阶练习

  1. 订单处理流程重构

    public class OrderValidator {
        public boolean isValid(String orderId, double totalAmount,
                               int itemCount, LocalDateTime createTime) {
            // 验证订单有效性逻辑...
        }
    }
    

综合练习

  1. 跨系统数据同步

    public class DataSync {
        public void syncProductInfo(int productId, String sku,
                                    BigDecimal price, int stock) {
            // 同步商品信息到外部系统...
        }
    }
    

代码审查清单

优势验证

  • 参数列表长度减少30%以上
  • 相关属性修改只需在对象中完成
  • 方法签名更清晰表达业务意图

风险提示

  • 可能引入不必要的对象依赖
  • 需要保证对象在调用链中的生命周期
  • 可能违反迪米特法则(Law of Demeter)