简介
"用函数调用替换内联代码"是提升代码复用性的基础重构手法。通过将重复出现的代码片段提取为独立函数,可以有效减少代码冗余,增强可维护性,并提升代码表达能力。
针对的症状(代码坏味道)
- 相同代码片段重复出现3次以上
- 包含复杂业务逻辑的内联代码
- 需要注释说明的代码块
- 难以理解的表达式组合
用函数调用替换内联代码的详细步骤
- 识别重复模式
- 使用代码对比工具查找相似代码块
- 标记具有相同语义的代码片段
- 创建目标函数
- 选择具有业务含义的函数名称
- 处理必要的参数和返回值
- 替换调用点
- 用函数调用替换原始代码
- 保持原有接口兼容性
- 验证重构
- 确保行为一致性
- 更新单元测试
示例
重构前代码:
class OrderProcessor {
void processOrder(Order order) {
// 计算折扣
double discount = order.getAmount() > 1000 ?
order.getAmount() * 0.1 : 0;
// 应用会员折扣
if (order.isVIP()) {
discount += order.getAmount() * 0.05;
}
// 其他处理逻辑...
}
void generateReport(Order order) {
// 计算折扣(重复逻辑)
double discount = order.getAmount() > 1000 ?
order.getAmount() * 0.1 : 0;
if (order.isVIP()) {
discount += order.getAmount() * 0.05;
}
// 生成报表逻辑...
}
}
重构步骤:
-
提取折扣计算函数:
private double calculateDiscount(Order order) { double discount = order.getAmount() > 1000 ? order.getAmount() * 0.1 : 0; if (order.isVIP()) { discount += order.getAmount() * 0.05; } return discount; } -
替换原始代码:
class OrderProcessor { void processOrder(Order order) { double discount = calculateDiscount(order); // 其他处理逻辑... } void generateReport(Order order) { double discount = calculateDiscount(order); // 生成报表逻辑... } }
练习
基础练习题
- 简单重复代码提取
// 重构前
class Circle {
double area(double radius) {
return 3.14159 * radius * radius;
}
double circumference(double radius) {
return 2 * 3.14159 * radius;
}
}
进阶练习题
-
带条件判断的代码提取
// 重构前 class StringValidator { boolean isValid(String s) { return s != null && !s.isEmpty() && s.length() <= 100; } String formatInput(String s) { if (s == null || s.isEmpty() || s.length() > 100) { return "Invalid"; } return s.trim(); } }
综合拓展练习题
-
多上下文重复逻辑
// 重构前 class InventoryService { void checkStock(Product p) { if (p.getStock() < 10 && p.isPopular()) { sendRestockAlert(p); } } void updatePrice(Product p) { if (p.getStock() < 10 && p.isPopular()) { applyPriceIncrease(p); } } }
代码审查要点
-
优点:
- 降低代码重复率
- 集中业务逻辑处理
- 提升可测试性
-
潜在问题:
- 避免创建无意义的小函数
- 保持函数单一职责原则
- 注意参数传递的正确性