重构手法——对象结构优化类 | 改进构造器 | 上移构造函数体

59 阅读2分钟

简介

"上移构造函数体"(Pull Up Constructor Body)重构手法用于消除子类构造函数中的重复初始化逻辑。当多个子类在构造函数中执行相同的初始化操作时,可以将这些公共逻辑移动到父类构造函数中。

典型代码坏味道

  • 子类构造函数包含相同的字段初始化代码
  • 父类缺乏必要的初始化逻辑
  • 重复的对象状态设置代码

重构步骤

  1. 识别重复逻辑

    • 找到子类构造函数中的相同代码块
    • 确认这些逻辑的通用性
    • 检查父类构造函数是否已存在类似逻辑
  2. 创建父类构造函数

    • 在父类中定义受保护/公共的构造函数
    • 将公共初始化逻辑移至父类
    • 使用模板方法模式处理差异点(如需)
  3. 调整子类实现

    • 使用super()调用父类构造函数
    • 保留子类特有的初始化逻辑
    • 删除重复代码
  4. 验证与测试

    • 确保继承链中的初始化顺序
    • 验证final字段的正确初始化
    • 检查多态方法的调用时机

示例

重构前:

```java
class Engineer extends Employee {
    private String skillSet;

    public Engineer(String name, String skillSet) {
        super(name);
        this.skillSet = skillSet;
        initializeEquipment(); // 公共初始化方法
        setupWorkstation();    // 公共初始化方法
    }
}

class Manager extends Employee {
    private int teamSize;

    public Manager(String name, int teamSize) {
        super(name);
        this.teamSize = teamSize;
        initializeEquipment(); // 公共初始化方法
        setupWorkstation();    // 公共初始化方法
    }
}
```

重构后:

abstract class Employee {
    protected Employee(String name) {
        initializeEquipment();
        setupWorkstation();
    }

    private void initializeEquipment() { /* 公共初始化逻辑 */ }

    private void setupWorkstation() { /* 公共初始化逻辑 */ }
}

class Engineer extends Employee {
    private String skillSet;

    public Engineer(String name, String skillSet) {
        super(name);
        this.skillSet = skillSet;
    }
}

class Manager extends Employee {
    private int teamSize;

    public Manager(String name, int teamSize) {
        super(name);
        this.teamSize = teamSize;
    }
}

专项练习

基础练习

  1. 重构车辆类继承体系

    class Car extends Vehicle {
        public Car(String model, int fuelCapacity) {
            super(model);
            this.fuelCapacity = fuelCapacity;
            checkSafetySystem(); // 公共方法
            calibrateEngine();   // 公共方法
        }
    }
    
    class Truck extends Vehicle {
        public Truck(String model, int cargoCapacity) {
            super(model);
            this.cargoCapacity = cargoCapacity;
            checkSafetySystem(); // 公共方法
            calibrateEngine();   // 公共方法
        }
    }
    

进阶练习

  1. 跨层级构造函数重构

    class Android extends MobileOS {
        public Android(String version) {
            super(version);
            loadKernelModules();
            initFileSystem();
            startRuntimeEnvironment();
        }
    }
    
    class IOS extends MobileOS {
        public IOS(String version) {
            super(version);
            loadKernelModules();
            initFileSystem();
            configureSandbox();
        }
    }
    

代码审查清单

优势验证

  • 子类构造函数代码量减少50%以上
  • 公共初始化逻辑集中维护
  • 保证父类状态正确性

风险提示

  • 可能破坏子类初始化顺序
  • 父类构造函数异常处理复杂度增加
  • 多线程环境下初始化竞态条件