重构手法——函数行为重塑类 | 函数签名 | 参数化方法

56 阅读2分钟

简介

"参数化方法"(Parameterize Method)是面向对象编程中消除重复方法逻辑的重构技术。当类中存在多个执行相同操作但使用不同常量值的方法时,通过将这些常量转换为方法参数来合并方法。

典型代码坏味道

  • 类中存在多个相似方法(Similar Methods)
  • 方法体内包含硬编码的业务规则
  • 仅参数类型不同但处理逻辑相同的重载方法

重构步骤

  1. 识别重复模式

    • 找到类中执行相同核心逻辑的方法
    • 标记方法间差异的常量或表达式
    • 确认方法签名兼容性
  2. 创建参数化方法

    • 选择具有最完整逻辑的方法作为基础
    • 将差异点转换为方法参数
    • 使用参数替换硬编码值
    • 保持原有方法作为兼容层(可选)
  3. 替换调用点

    • 修改客户端调用传入新参数
    • 逐步替换旧方法调用
    • 删除已废弃的旧方法
  4. 验证与测试

    • 确保参数边界条件处理
    • 验证多态方法的正确覆盖
    • 维护子类重写逻辑的兼容性

示例

原始类方法:

public class OrderProcessor {
    // 处理国内订单
    public void processDomesticOrder(Order order) {
        validateAddress(order);
        applyTaxRate(order, 0.13); // 固定13%税率
        applyShippingRule(order, "standard");
    }

    // 处理国际订单
    public void processInternationalOrder(Order order) {
        validateAddress(order);
        applyTaxRate(order, 0.05); // 固定5%税率
        applyShippingRule(order, "express");
    }
}

重构后的参数化方法:

```java
public class OrderProcessor {
    public void processOrder(Order order, double taxRate, String shippingType) {
        validateAddress(order);
        applyTaxRate(order, taxRate);
        applyShippingRule(order, shippingType);
    }

    // 保留原方法作为便捷方法
    public void processDomesticOrder(Order order) {
        processOrder(order, 0.13, "standard");
    }

    @Deprecated
    public void processInternationalOrder(Order order) {
        processOrder(order, 0.05, "express");
    }
}
```

专项练习

基础练习

  1. 重构支付处理方法

    public class PaymentHandler {
        public void handleCreditCardPayment(double amount) {
            processPayment(amount, 0.02); // 2%手续费
        }
    
        public void handlePayPalPayment(double amount) {
            processPayment(amount, 0.03); // 3%手续费
        }
    
        private void processPayment(double amount, double feeRate) {
            double total = amount * (1 + feeRate);
            // 支付处理逻辑...
        }
    }
    

进阶练习

  1. 多维度参数化重构

    public class ReportGenerator {
        public void generateDailyReport() {
            prepareData(LocalDate.now().minusDays(1));
            formatReport("PDF");
            setFrequency(DAILY);
        }
    
        public void generateWeeklyReport() {
            prepareData(LocalDate.now().minusWeeks(1));
            formatReport("EXCEL");
            setFrequency(WEEKLY);
        }
    
        // 待参数化的核心逻辑...
    }
    

综合练习

  1. 跨类方法参数化
public class CustomerService {
    public void respondToComplaint() {
        String template = loadTemplate("complaint_response");
        String signature = getManagerSignature();
        sendEmail(template, signature);
    }
    
    public void sendPromotionNotice() {
        String template = loadTemplate("promotion_notice"); 
        String signature = getSalesSignature();
        sendEmail(template, signature);
    }
    
    // 公共邮件发送逻辑...
}

代码审查清单

优势验证

  • 是否保持合理的向后兼容
  • 参数命名是否准确反映业务含义
  • 是否保留必要的重载方法

风险提示

  • 方法参数过多影响可读性
  • 破坏现有子类的方法重写
  • 未处理的参数组合异常