简介
"提取子类"是处理类中变化行为的有效重构手法。通过将特殊逻辑分离到子类中,可以简化父类结构,提高代码的可扩展性和多态处理能力。
针对的症状(代码坏味道)
- 类中存在仅部分实例使用的特性
- 使用标志参数控制不同行为
- 需要为特定情况添加异常处理
- 存在大量条件判断逻辑
提取子类的详细步骤
- 识别变化点
- 查找类中的条件分支逻辑
- 标记特殊行为代码块
- 创建子类
- 继承原始类建立子类
- 使用工厂方法封装创建逻辑
- 迁移特性
- 将特殊行为移至子类
- 用多态替代条件判断
- 清理父类
- 移除不再需要的标志字段
- 保持父子类职责清晰
示例
重构前代码:
class Order {
private boolean isPriority;
double getDeliveryDays() {
return isPriority ? 2 : 5;
}
double getFee() {
return isPriority ? 10 : 0;
}
}
重构步骤:
-
创建PriorityOrder子类:
class PriorityOrder extends Order { @Override double getDeliveryDays() { return 2; } @Override double getFee() { return 10; } } -
重构Order类:
class Order { static Order create(boolean isPriority) { return isPriority ? new PriorityOrder() : new Order(); } double getDeliveryDays() { return 5; } double getFee() { return 0; } }
练习
基础练习题
-
简单子类提取
// 重构前 class Product { private boolean isDigital; double getShippingCost() { return isDigital ? 0 : 5; } }
进阶练习题
-
复合行为迁移
// 重构前 class Employee { private int type; // 0=REGULAR, 1=MANAGER double getBonus() { return type == 1 ? 2000 : 1000; } }
综合拓展练习题
-
多特性子类
// 重构前 class InsurancePolicy { private boolean isCorporate; private boolean isInternational; double getDiscountRate() { if (isCorporate && isInternational) return 0.2; if (isCorporate) return 0.15; return 0; } }
代码审查要点
-
优点:
- 明确类层次关系
- 消除条件判断
- 支持开闭原则
-
潜在问题:
- 控制子类数量
- 保持工厂方法简洁
- 避免过度继承