简介
"用类替换类型代码"是提升类型安全性的关键重构手法。通过将简单的类型标识符封装为独立类,可以强化类型约束,集中相关行为,并增强代码的可扩展性。
针对的症状(代码坏味道)
- 使用原始值表示类型或状态
- 类型代码需要关联特定行为
- 存在大量针对类型代码的条件判断
- 需要扩展类型代码的附加属性
用类替换类型代码的详细步骤
- 识别类型代码
- 查找表示类型的原始值
- 标记相关条件判断逻辑
- 创建类型类
- 封装类型代码值为常量
- 添加类型校验方法
- 迁移关联行为
- 将类型相关逻辑移至新类
- 使用多态替代条件判断
- 替换类型引用
- 用类型类替换原始类型声明
- 更新类型校验逻辑
示例
重构前代码:
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;
}
}
重构步骤:
-
创建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; } } -
重构Product类:
class Product { private ProductType type; double getTaxRate() { return type.getTaxRate(); } }
练习
基础练习题
-
简单类型替换
// 重构前 class User { private String role; // "ADMIN", "GUEST" }
进阶练习题
-
带行为的类型类
// 重构前 class Order { private int status; // 1=NEW, 2=PAID boolean canCancel() { return status == 1; } }
综合拓展练习题
-
复合类型系统
// 重构前 class Vehicle { private String category; // "CAR", "TRUCK" int getMaxSpeed() { if ("CAR".equals(category)) return 120; if ("TRUCK".equals(category)) return 90; return 0; } }
代码审查要点
-
优点:
- 增强类型安全性
- 集中类型相关逻辑
- 支持多态扩展
-
潜在问题:
- 控制类型类的数量
- 保持类型系统简洁
- 注意序列化兼容性