重构手法——函数行为重塑类 | 语意 | 提取子类

48 阅读2分钟

简介

"提取子类"是处理类中变化行为的有效重构手法。通过将特殊逻辑分离到子类中,可以简化父类结构,提高代码的可扩展性和多态处理能力。

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

  • 类中存在仅部分实例使用的特性
  • 使用标志参数控制不同行为
  • 需要为特定情况添加异常处理
  • 存在大量条件判断逻辑

提取子类的详细步骤

  1. 识别变化点
    • 查找类中的条件分支逻辑
    • 标记特殊行为代码块
  2. 创建子类
    • 继承原始类建立子类
    • 使用工厂方法封装创建逻辑
  3. 迁移特性
    • 将特殊行为移至子类
    • 用多态替代条件判断
  4. 清理父类
    • 移除不再需要的标志字段
    • 保持父子类职责清晰

示例

重构前代码:

class Order {
    private boolean isPriority;

    double getDeliveryDays() {
        return isPriority ? 2 : 5;
    }

    double getFee() {
        return isPriority ? 10 : 0;
    }
}

重构步骤:

  1. 创建PriorityOrder子类:

    class PriorityOrder extends Order {
        @Override
        double getDeliveryDays() {
            return 2;
        }
    
        @Override
        double getFee() {
            return 10;
        }
    }
    
  2. 重构Order类:

    class Order {
        static Order create(boolean isPriority) {
            return isPriority ? new PriorityOrder() : new Order();
        }
    
        double getDeliveryDays() {
            return 5;
        }
    
        double getFee() {
            return 0;
        }
    }
    

练习

基础练习题

  1. 简单子类提取

    // 重构前
    class Product {
        private boolean isDigital;
    
        double getShippingCost() {
            return isDigital ? 0 : 5;
        }
    }
    

进阶练习题

  1. 复合行为迁移

    // 重构前
    class Employee {
        private int type; // 0=REGULAR, 1=MANAGER
    
        double getBonus() {
            return type == 1 ? 2000 : 1000;
        }
    }
    

综合拓展练习题

  1. 多特性子类

    // 重构前
    class InsurancePolicy {
        private boolean isCorporate;
        private boolean isInternational;
    
        double getDiscountRate() {
            if (isCorporate && isInternational) return 0.2;
            if (isCorporate) return 0.15;
            return 0;
        }
    }
    

代码审查要点

  1. 优点:

    • 明确类层次关系
    • 消除条件判断
    • 支持开闭原则
  2. 潜在问题:

    • 控制子类数量
    • 保持工厂方法简洁
    • 避免过度继承