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

39 阅读2分钟

简介

"参数化函数"(Parameterize Function)是一种通过将函数中的字面量值转换为参数来提高代码复用性的重构手法。当发现多个相似函数仅在少量值上存在差异时,可以将这些值参数化来合并函数。

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

  • 重复的代码(Duplicated Code)
  • 相似的函数(Similar Functions)
  • 硬编码的常量(Hard-Coded Literals)

参数化函数(Parameterize Function)的详细步骤

  1. 识别参数化机会

    • 找到执行相同操作但使用不同字面量值的多个函数
    • 检查函数中可能变化的硬编码值
    • 确保参数化不会破坏现有功能
  2. 创建参数化函数

    • 选择其中一个函数作为基础模板
    • 将需要变化的字面量值转换为参数
    • 调整方法签名添加新参数
    • 更新方法内部逻辑使用新参数
  3. 替换原始调用

    • 修改原调用方传入新的参数值
    • 删除其他相似函数
    • 确保所有测试用例通过
  4. 测试验证

    • 验证参数边界条件
    • 测试所有可能的参数组合
    • 保持原有功能不变

示例

原始代码:

public class DiscountCalculator {
    // 两个高度相似的折扣计算方法
    public double calculateFivePercentDiscount(double price) {
        return price * 0.95;
    }

    public double calculateTenPercentDiscount(double price) {
        return price * 0.90;
    }
}

重构步骤:

  1. 识别重复模式:两个方法仅折扣率不同

  2. 创建参数化方法:

    public class DiscountCalculator {
        public double calculateDiscount(double price, double discountRate) {
            return price * (1 - discountRate);
        }
    }
    
  3. 替换原始调用:

// 原调用方式替换为:
    new DiscountCalculator().calculateDiscount(100, 0.05); // 5%折扣
    new DiscountCalculator().calculateDiscount(100, 0.10); // 10%折扣

练习

基础练习

  1. 参数化税率计算

    public class TaxCalculator {
        public double calculateUSTax(double income) {
            return income * 0.30; // 美国税率30%
        }
    
        public double calculateEUTax(double income) {
            return income * 0.45; // 欧洲税率45%
        }
    }
    

进阶练习

  1. 多参数化重构

    public class Geometry {
        public double circleArea(double radius) {
            return Math.PI * radius * radius;
        }
    
        public double cylinderVolume(double radius, double height) {
            return Math.PI * radius * radius * height;
        }
    
        public double coneVolume(double radius, double height) {
            return Math.PI * radius * radius * height / 3;
        }
    }
    

综合练习

  1. 电商系统价格计算

    public class PriceStrategy {
        // VIP折扣策略
        public double applyVipDiscount(double price) {
            return price * 0.80; // 20% off
        }
    
        // 节日折扣策略
        public double applyHolidayDiscount(double price) {
            return price * 0.70; // 30% off
        }
    
        // 清仓折扣策略
        public double applyClearanceDiscount(double price) {
            return price * 0.50; // 50% off
        }
    }
    

代码审查要点

  1. 优点检查

    • 是否消除重复代码
    • 参数命名是否清晰
    • 是否保留必要的类型检查
  2. 潜在问题

    • 参数组合爆炸风险
    • 缺少参数校验
    • 过度参数化导致方法复杂