重构手法——函数行为重塑类 | 语意 | 用类替换类型代码

46 阅读2分钟

简介

"用类替换类型代码"是提升类型安全性的关键重构手法。通过将简单的类型标识符封装为独立类,可以强化类型约束,集中相关行为,并增强代码的可扩展性。

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

  • 使用原始值表示类型或状态
  • 类型代码需要关联特定行为
  • 存在大量针对类型代码的条件判断
  • 需要扩展类型代码的附加属性

用类替换类型代码的详细步骤

  1. 识别类型代码
    • 查找表示类型的原始值
    • 标记相关条件判断逻辑
  2. 创建类型类
    • 封装类型代码值为常量
    • 添加类型校验方法
  3. 迁移关联行为
    • 将类型相关逻辑移至新类
    • 使用多态替代条件判断
  4. 替换类型引用
    • 用类型类替换原始类型声明
    • 更新类型校验逻辑

示例

重构前代码:

class Product {
    private String type; // "BOOK", "ELECTRONIC"

    double getTaxRate() {
        if ("BOOK".equals(type)) return 0.05;
        if ("ELECTRONIC".equals(type)) return 0.15;
        return 0;
    }
}

重构步骤:

  1. 创建ProductType类:

    class ProductType {
        public static final ProductType BOOK = new ProductType("BOOK", 0.05);
        public static final ProductType ELECTRONIC = new ProductType("ELECTRONIC", 0.15);
    
        private final String code;
        private final double taxRate;
    
        private ProductType(String code, double taxRate) {
            this.code = code;
            this.taxRate = taxRate;
        }
    
        public double getTaxRate() {
            return taxRate;
        }
    }
    
  2. 重构Product类:

    class Product {
        private ProductType type;
    
        double getTaxRate() {
            return type.getTaxRate();
        }
    }
    

练习

基础练习题

  1. 简单类型替换

    // 重构前
    class User {
        private String role; // "ADMIN", "GUEST"
    }
    

进阶练习题

  1. 带行为的类型类

    // 重构前
    class Order {
        private int status; // 1=NEW, 2=PAID
    
        boolean canCancel() {
            return status == 1;
        }
    }
    

综合拓展练习题

  1. 复合类型系统

    // 重构前
    class Vehicle {
        private String category; // "CAR", "TRUCK"
    
        int getMaxSpeed() {
            if ("CAR".equals(category)) return 120;
            if ("TRUCK".equals(category)) return 90;
            return 0;
        }
    }
    

代码审查要点

  1. 优点:

    • 增强类型安全性
    • 集中类型相关逻辑
    • 支持多态扩展
  2. 潜在问题:

    • 控制类型类的数量
    • 保持类型系统简洁
    • 注意序列化兼容性