重构手法——函数行为重塑类 | 语意 | 用字段替换子类

44 阅读2分钟

简介

"用字段替换子类"(Replace Subclass with Fields)重构手法用于简化仅包含常量差异的继承体系。当子类差异仅体现在返回固定值时,应该用父类字段替代子类。

典型代码坏味道

  • 子类仅覆盖返回常量的方法
  • 子类没有行为差异
  • 存在大量只包含工厂方法的子类
  • 子类构造函数仅设置固定值

重构步骤

  1. 识别简单子类

    • 找到只返回固定值的子类
    • 分析子类的方法差异
    • 确认子类没有其他行为
  2. 提升字段到父类

    • 在父类中添加类型标识字段
    • 创建包含所有可能值的枚举
    • 用字段替代方法返回值
  3. 调整工厂方法

    • 用静态工厂方法替代子类
    • 修改客户端创建代码
    • 处理遗留的子类引用
  4. 验证与测试

    • 检查所有类型相关逻辑
    • 验证字段初始化正确性
    • 确保序列化兼容性

示例

重构前:

abstract class BloodType {
    abstract String getSymbol();
}

class A extends BloodType {
    String getSymbol() {
        return "A";
    }
}

class B extends BloodType {
    String getSymbol() {
        return "B";
    }
}

重构后:

class BloodType {
    private String symbol;

    private BloodType(String symbol) {
        this.symbol = symbol;
    }

    public static BloodType A() {
        return new BloodType("A");
    }

    public static BloodType B() {
        return new BloodType("B");
    }
}

专项练习

基础练习

  1. 重构行星重力常量

    abstract class Planet {
        abstract double gravity();
    }
    
    class Earth extends Planet {
        double gravity() {
            return 9.8;
        }
    }
    
    class Mars extends Planet {
        double gravity() {
            return 3.7;
        }
    }
    

进阶练习

  1. 处理国际汇率类型

    abstract class Currency {
        abstract String code();
    
        abstract String symbol();
    }
    
    class USD extends Currency {
        String code() {
            return "USD";
        }
    
        String symbol() {
            return "$";
        }
    }
    

代码审查清单

优势验证

  • 类数量减少80%以上
  • 消除不必要的类型层次
  • 提高代码可维护性

风险提示

  • 需要修改工厂方法逻辑
  • 可能增加父类复杂度
  • 影响现有的instanceof检查