简介
"下移方法"(Push Down Method)是将超类中只与特定子类相关的方法迁移到子类的重构手法。该方法用于解决不合理的继承层次结构,提高代码的内聚性。
针对的症状(代码坏味道)
- 超类中存在只被部分子类使用的方法
- 子类中出现方法覆盖但父类方法未被复用
- 违反里氏替换原则(LSP)的方法实现
下移方法的详细步骤
-
识别需要下移的方法
- 检查父类方法被哪些子类使用
- 确认方法是否与父类核心职责无关
- 验证方法是否只与特定子类相关
-
在子类中创建方法
- 将方法复制到相关子类
- 保持相同的签名和实现
- 添加@Override注解(Java)
-
移除超类方法
- 删除超类中的原始方法
- 处理可能存在的继承链断裂
- 更新文档注释
-
测试验证
- 确保所有调用方正常运作
- 验证子类特有功能不受影响
- 检查多态调用场景
-
后续优化
- 将子类特有的字段也下移
- 重构与下移方法相关的其他方法
- 考虑是否需要创建新的子类
示例
重构前继承体系:
abstract class Animal {
void fly() {
// 飞行通用实现
}
}
class Dog extends Animal {
// 不需要飞行能力
}
class Bird extends Animal {
// 需要飞行能力
}
重构步骤:
-
将fly方法下移到Bird类:
abstract class Animal { // 移除fly方法 } class Bird extends Animal { @Override void fly() { // 飞行具体实现 } } -
保持Dog类纯净:
class Dog extends Animal { // 不再继承不需要的方法 }
练习
基础练习题
- 简单方法下移
-
重构以下Shape类,将drawCircle方法下移到Circle子类:
abstract class Shape { void drawCircle() { System.out.println("绘制圆形"); } } class Circle extends Shape { } class Square extends Shape { }
-
进阶练习题
- 带参数方法下移
-
重构Employee体系,将calculateBonus方法下移到Manager子类:
abstract class Employee { public double calculateBonus(double base) { return base * 2.5; } } class Manager extends Employee { } class Staff extends Employee { }
-
综合拓展练习
-
多层级方法下移
-
重构车辆继承体系,将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方法 }
-
-
代码审查模拟
- 当完成上述重构后,模拟审查发现:
- 优点:消除Car类不必要的货运检查能力
- 潜在问题:ContainerTruck可能需要不同的检查逻辑
- 改进建议:考虑创建CargoVehicle中间抽象类
- 当完成上述重构后,模拟审查发现: