简介
"用查询替换参数"是简化方法接口的重要重构手法。通过将参数计算逻辑移至方法内部,可以减少参数传递层级,提高方法的内聚性并降低调用复杂度。
针对的症状(代码坏味道)
- 方法参数可从其他参数推导得出
- 参数值依赖对象内部状态
- 多个方法使用相同参数计算逻辑
- 参数传递导致调用链过长
用查询替换参数的详细步骤
- 识别候选参数
- 查找可被其他参数推导的参数
- 确认参数值的确定性来源
- 提取参数计算逻辑
- 将参数计算封装为查询方法
- 确保计算逻辑无副作用
- 修改方法签名
- 移除目标参数声明
- 更新方法内部引用
- 重构调用方
- 移除调用处的参数传递
- 保持原有业务逻辑不变
示例
重构前代码:
class OrderService {
double getDiscountedPrice(Order order, boolean isVIP) {
double basePrice = order.getAmount();
return isVIP ? basePrice * 0.9 : basePrice;
}
void applyDiscount(Order order, boolean isVIP) {
double finalPrice = getDiscountedPrice(order, isVIP);
order.setFinalPrice(finalPrice);
}
}
重构步骤:
-
将isVIP参数改为内部查询:
class OrderService { double getDiscountedPrice(Order order) { double basePrice = order.getAmount(); return isVIP(order) ? basePrice * 0.9 : basePrice; } private boolean isVIP(Order order) { return order.getCustomer().isVIP(); } void applyDiscount(Order order) { double finalPrice = getDiscountedPrice(order); order.setFinalPrice(finalPrice); } }
练习
基础练习题
-
简单参数替换
// 重构前 class Calculator { double circleArea(double radius, double pi) { return pi * radius * radius; } }
进阶练习题
-
对象状态参数替换
// 重构前 class Employee { void applyRaise(double performanceScore, double salary) { if (performanceScore > 0.8) { salary *= 1.1; } this.salary = salary; } }
综合拓展练习题
-
多参数替换
// 重构前 class ShippingService { double calculateCost(double weight, double size, boolean isInternational) { double base = weight * size; return isInternational ? base * 1.3 : base; } }
代码审查要点
-
优点:
- 简化方法调用接口
- 集中核心计算逻辑
- 减少参数传递错误
-
潜在问题:
- 确保查询方法幂等性
- 避免引入隐藏依赖
- 注意计算性能影响