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

57 阅读2分钟

简介

"下移方法"(Push Down Method)是将超类中只与特定子类相关的方法迁移到子类的重构手法。该方法用于解决不合理的继承层次结构,提高代码的内聚性。

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

  • 超类中存在只被部分子类使用的方法
  • 子类中出现方法覆盖但父类方法未被复用
  • 违反里氏替换原则(LSP)的方法实现

下移方法的详细步骤

  1. 识别需要下移的方法

    • 检查父类方法被哪些子类使用
    • 确认方法是否与父类核心职责无关
    • 验证方法是否只与特定子类相关
  2. 在子类中创建方法

    • 将方法复制到相关子类
    • 保持相同的签名和实现
    • 添加@Override注解(Java)
  3. 移除超类方法

    • 删除超类中的原始方法
    • 处理可能存在的继承链断裂
    • 更新文档注释
  4. 测试验证

    • 确保所有调用方正常运作
    • 验证子类特有功能不受影响
    • 检查多态调用场景
  5. 后续优化

    • 将子类特有的字段也下移
    • 重构与下移方法相关的其他方法
    • 考虑是否需要创建新的子类

示例

重构前继承体系:

abstract class Animal {
    void fly() {
        // 飞行通用实现
    }
}

class Dog extends Animal {
    // 不需要飞行能力
}

class Bird extends Animal {
    // 需要飞行能力
}

重构步骤:

  1. 将fly方法下移到Bird类:

    abstract class Animal {
        // 移除fly方法
    }
    
    class Bird extends Animal {
        @Override
        void fly() {
            // 飞行具体实现
        }
    }
    
  2. 保持Dog类纯净:

    class Dog extends Animal {
        // 不再继承不需要的方法
    }
    

练习

基础练习题

  1. 简单方法下移
    • 重构以下Shape类,将drawCircle方法下移到Circle子类:

      abstract class Shape {
          void drawCircle() {
              System.out.println("绘制圆形");
          }
      }
      
      class Circle extends Shape {
      }
      
      class Square extends Shape {
      }
      

进阶练习题

  1. 带参数方法下移
    • 重构Employee体系,将calculateBonus方法下移到Manager子类:

      abstract class Employee {
          public double calculateBonus(double base) {
              return base * 2.5;
          }
      }
      
      class Manager extends Employee {
      }
      
      class Staff extends Employee {
      }
      

综合拓展练习

  1. 多层级方法下移

    • 重构车辆继承体系,将checkCargo方法下移到Truck子类:

      abstract class Vehicle {
          boolean checkCargo(int weight) {
              return weight < 1000;
          }
      }
      
      class Car extends Vehicle {
      }
      
      class Truck extends Vehicle {
          // 需要重写货物检查逻辑
      }
      
      class ContainerTruck extends Truck {
          // 需要继承checkCargo方法
      }
      
  2. 代码审查模拟

    • 当完成上述重构后,模拟审查发现:
      • 优点:消除Car类不必要的货运检查能力
      • 潜在问题:ContainerTruck可能需要不同的检查逻辑
      • 改进建议:考虑创建CargoVehicle中间抽象类