重构手法——对象结构优化类 | 改进构造器 | 下移字段

51 阅读2分钟

简介

"下移字段"(Push Down Field)重构手法用于处理父类中存在仅被部分子类使用的字段。当某个字段在父类中定义但实际只被少数子类使用时,将其移至真正需要该字段的子类。

典型代码坏味道

  • 父类字段被少数子类使用
  • 子类中存在冗余的字段定义
  • 父类字段在多数子类中被设为null或默认值

重构步骤

  1. 识别字段使用范围

    • 找到父类中未被所有子类使用的字段
    • 分析字段在各子类中的访问模式
    • 检查字段初始化方式的差异
  2. 在子类中声明字段

    • 在需要该字段的子类中创建相同字段
    • 调整访问修饰符(通常为protected)
    • 保持父类现有构造函数不变
  3. 移除父类字段

    • 删除父类中的冗余字段声明
    • 修改父类中直接访问该字段的代码
    • 处理可能存在的继承链访问
  4. 验证与测试

    • 检查序列化兼容性
    • 验证反射操作的字段存在性
    • 确保数据库映射完整性

示例

重构前:

abstract class Vehicle {
    protected int wingCount; // 仅飞机类需要
    // 其他公共字段...
}

class Airplane extends Vehicle {
    void fly() {
        System.out.println("Flying with " + wingCount + " wings");
    }
}

class Car extends Vehicle {
    // wingCount 字段在此类中无用
}

重构后:

abstract class Vehicle {
    // 其他公共字段...
}

class Airplane extends Vehicle {
    protected int wingCount;

    void fly() {
        System.out.println("Flying with " + wingCount + " wings");
    }
}

class Car extends Vehicle {
    // 不再包含无用字段
}

专项练习

基础练习

  1. 重构动物类继承体系

    abstract class Animal {
        protected int hornCount; // 仅山羊类需要
    }
    
    class Goat extends Animal {
        void showHorns() {
            System.out.println(hornCount + " horns");
        }
    }
    
    class Duck extends Animal {
        // hornCount 字段在此类中无用
    }
    

进阶练习

  1. 多层级字段下移

    abstract class Database {
        protected NoSQLConfig nosqlConfig; // 仅NoSQL子类需要
    }
    
    class SQLDatabase extends Database {
        // 不需要NoSQL配置
    }
    
    class MongoDB extends Database {
        void setup() {
            nosqlConfig.applySettings();
        }
    }
    

代码审查清单

优势验证

  • 父类字段冗余度降低70%以上
  • 子类字段使用率提升至100%
  • 消除不必要的默认值初始化

风险提示

  • 可能破坏使用父类类型的客户端代码
  • 需要同步修改关联的工厂方法
  • 影响使用反射获取字段的逻辑