用枚举类消除多个 if-else
使用枚举类(Enum)是一种优雅的方式来替代冗长的 if-else 或 switch 语句,提高代码的可读性和可维护性。
📋 目录
🔍 问题场景
典型的 if-else 代码
在实际开发中,我们经常会遇到这样的代码:
java
public class OrderService {
public void processOrder(String orderType) {
if ("ONLINE".equals(orderType)) {
System.out.println("处理在线订单");
// 在线订单处理逻辑
validateOnlinePayment();
sendConfirmationEmail();
} else if ("OFFLINE".equals(orderType)) {
System.out.println("处理线下订单");
// 线下订单处理逻辑
validateCashPayment();
printReceipt();
} else if ("WHOLESALE".equals(orderType)) {
System.out.println("处理批发订单");
// 批发订单处理逻辑
validateCreditLimit();
generateInvoice();
} else if ("RETAIL".equals(orderType)) {
System.out.println("处理零售订单");
// 零售订单处理逻辑
validateStock();
updateInventory();
} else {
throw new IllegalArgumentException("未知的订单类型: " + orderType);
}
}
}❌ 传统方案的问题
1. 代码冗长难维护
java
// 每增加一种类型,就要添加一个 if-else 分支
if ("TYPE_A".equals(type)) {
// 逻辑 A
} else if ("TYPE_B".equals(type)) {
// 逻辑 B
} else if ("TYPE_C".equals(type)) {
// 逻辑 C
}
// ... 可能有几十个分支2. 容易出错
java
// 字符串常量容易写错
if ("ONLNIE".equals(orderType)) { // 拼写错误!
// ...
}
// 大小写敏感
if ("online".equals(orderType)) { // 应该是 "ONLINE"
// ...
}3. 缺乏类型安全
java
// 可以传入任意字符串,编译时无法检查
processOrder("INVALID_TYPE"); // 运行时才会发现错误4. 难以扩展
java
// 添加新类型需要修改多处代码
// 1. 添加 if-else 分支
// 2. 可能需要修改相关的常量定义
// 3. 更新文档和测试✅ 枚举类解决方案
1. 基础枚举实现
java
/**
* 订单类型枚举
*/
public enum OrderType {
ONLINE("在线订单"),
OFFLINE("线下订单"),
WHOLESALE("批发订单"),
RETAIL("零售订单");
private final String description;
OrderType(String description) {
this.description = description;
}
public String getDescription() {
return description;
}
}
/**
* 使用枚举的订单服务
*/
public class OrderService {
public void processOrder(OrderType orderType) {
switch (orderType) {
case ONLINE:
System.out.println("处理" + orderType.getDescription());
validateOnlinePayment();
sendConfirmationEmail();
break;
case OFFLINE:
System.out.println("处理" + orderType.getDescription());
validateCashPayment();
printReceipt();
break;
case WHOLESALE:
System.out.println("处理" + orderType.getDescription());
validateCreditLimit();
generateInvoice();
break;
case RETAIL:
System.out.println("处理" + orderType.getDescription());
validateStock();
updateInventory();
break;
}
}
}
// 使用示例
OrderService service = new OrderService();
service.processOrder(OrderType.ONLINE); // 类型安全,编译时检查2. 枚举中封装行为(推荐)
java
/**
* 在枚举中直接封装处理逻辑
*/
public enum OrderType {
ONLINE("在线订单") {
@Override
public void process() {
System.out.println("处理" + getDescription());
validateOnlinePayment();
sendConfirmationEmail();
}
},
OFFLINE("线下订单") {
@Override
public void process() {
System.out.println("处理" + getDescription());
validateCashPayment();
printReceipt();
}
},
WHOLESALE("批发订单") {
@Override
public void process() {
System.out.println("处理" + getDescription());
validateCreditLimit();
generateInvoice();
}
},
RETAIL("零售订单") {
@Override
public void process() {
System.out.println("处理" + getDescription());
validateStock();
updateInventory();
}
};
private final String description;
OrderType(String description) {
this.description = description;
}
public String getDescription() {
return description;
}
/**
* 抽象方法,每个枚举常量必须实现
*/
public abstract void process();
// 辅助方法(可以被所有枚举常量调用)
protected void validateOnlinePayment() {
System.out.println("验证在线支付");
}
protected void sendConfirmationEmail() {
System.out.println("发送确认邮件");
}
protected void validateCashPayment() {
System.out.println("验证现金支付");
}
protected void printReceipt() {
System.out.println("打印收据");
}
protected void validateCreditLimit() {
System.out.println("验证信用额度");
}
protected void generateInvoice() {
System.out.println("生成发票");
}
protected void validateStock() {
System.out.println("验证库存");
}
protected void updateInventory() {
System.out.println("更新库存");
}
}
/**
* 简化后的订单服务
*/
public class OrderService {
public void processOrder(OrderType orderType) {
// 一行代码完成所有处理
orderType.process();
}
}
// 使用示例
OrderService service = new OrderService();
service.processOrder(OrderType.ONLINE);
service.processOrder(OrderType.WHOLESALE);3. 使用策略模式 + 枚举
java
/**
* 订单处理策略接口
*/
public interface OrderProcessor {
void process();
}
/**
* 在线订单处理器
*/
public class OnlineOrderProcessor implements OrderProcessor {
@Override
public void process() {
System.out.println("处理在线订单");
// 具体实现
}
}
/**
* 线下订单处理器
*/
public class OfflineOrderProcessor implements OrderProcessor {
@Override
public void process() {
System.out.println("处理线下订单");
// 具体实现
}
}
/**
* 枚举关联策略
*/
public enum OrderType {
ONLINE("在线订单", new OnlineOrderProcessor()),
OFFLINE("线下订单", new OfflineOrderProcessor()),
WHOLESALE("批发订单", new WholesaleOrderProcessor()),
RETAIL("零售订单", new RetailOrderProcessor());
private final String description;
private final OrderProcessor processor;
OrderType(String description, OrderProcessor processor) {
this.description = description;
this.processor = processor;
}
public void process() {
processor.process();
}
public String getDescription() {
return description;
}
}🚀 高级用法
1. 枚举实现接口
java
/**
* 计算策略接口
*/
public interface Calculator {
double calculate(double a, double b);
}
/**
* 运算符枚举
*/
public enum Operator implements Calculator {
ADD("+") {
@Override
public double calculate(double a, double b) {
return a + b;
}
},
SUBTRACT("-") {
@Override
public double calculate(double a, double b) {
return a - b;
}
},
MULTIPLY("*") {
@Override
public double calculate(double a, double b) {
return a * b;
}
},
DIVIDE("/") {
@Override
public double calculate(double a, double b) {
if (b == 0) {
throw new ArithmeticException("除数不能为零");
}
return a / b;
}
};
private final String symbol;
Operator(String symbol) {
this.symbol = symbol;
}
public String getSymbol() {
return symbol;
}
/**
* 根据符号获取运算符
*/
public static Operator fromSymbol(String symbol) {
for (Operator op : values()) {
if (op.symbol.equals(symbol)) {
return op;
}
}
throw new IllegalArgumentException("未知的运算符: " + symbol);
}
}
// 使用示例
public class CalculatorDemo {
public static void main(String[] args) {
double result1 = Operator.ADD.calculate(10, 5); // 15.0
double result2 = Operator.MULTIPLY.calculate(10, 5); // 50.0
// 动态选择运算符
Operator op = Operator.fromSymbol("+");
double result3 = op.calculate(10, 5); // 15.0
}
}2. 枚举 + Map 映射
java
/**
* 支付方式枚举
*/
public enum PaymentMethod {
ALIPAY("支付宝", "alipay"),
WECHAT("微信支付", "wechat"),
CREDIT_CARD("信用卡", "credit_card"),
CASH("现金", "cash");
private final String name;
private final String code;
// 静态 Map 用于快速查找
private static final Map<String, PaymentMethod> CODE_MAP = new HashMap<>();
static {
for (PaymentMethod method : values()) {
CODE_MAP.put(method.code, method);
}
}
PaymentMethod(String name, String code) {
this.name = name;
this.code = code;
}
public String getName() {
return name;
}
public String getCode() {
return code;
}
/**
* 根据代码获取支付方式(O(1) 时间复杂度)
*/
public static PaymentMethod fromCode(String code) {
PaymentMethod method = CODE_MAP.get(code);
if (method == null) {
throw new IllegalArgumentException("未知的支付方式代码: " + code);
}
return method;
}
/**
* 处理支付
*/
public void processPayment(double amount) {
System.out.println("使用" + name + "支付: ¥" + amount);
// 具体支付逻辑
}
}
// 使用示例
public class PaymentDemo {
public static void main(String[] args) {
// 从外部系统获取支付代码
String paymentCode = "alipay";
// 快速查找并处理
PaymentMethod method = PaymentMethod.fromCode(paymentCode);
method.processPayment(100.00);
}
}3. 枚举单例模式
java
/**
* 使用枚举实现线程安全的单例
*/
public enum DatabaseConnection {
INSTANCE;
private Connection connection;
DatabaseConnection() {
// 初始化数据库连接
try {
this.connection = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/mydb",
"username",
"password"
);
} catch (SQLException e) {
throw new RuntimeException("数据库连接失败", e);
}
}
public Connection getConnection() {
return connection;
}
public void executeQuery(String sql) {
// 执行查询
System.out.println("执行SQL: " + sql);
}
}
// 使用示例
DatabaseConnection.INSTANCE.executeQuery("SELECT * FROM users");💼 实战案例
案例 1:订单状态流转
java
/**
* 订单状态枚举
*/
public enum OrderStatus {
PENDING("待支付") {
@Override
public OrderStatus next() {
return PAID;
}
@Override
public boolean canCancel() {
return true;
}
},
PAID("已支付") {
@Override
public OrderStatus next() {
return SHIPPING;
}
@Override
public boolean canCancel() {
return true;
}
},
SHIPPING("配送中") {
@Override
public OrderStatus next() {
return DELIVERED;
}
@Override
public boolean canCancel() {
return false;
}
},
DELIVERED("已送达") {
@Override
public OrderStatus next() {
return COMPLETED;
}
@Override
public boolean canCancel() {
return false;
}
},
COMPLETED("已完成") {
@Override
public OrderStatus next() {
throw new IllegalStateException("订单已完成,无法继续流转");
}
@Override
public boolean canCancel() {
return false;
}
},
CANCELLED("已取消") {
@Override
public OrderStatus next() {
throw new IllegalStateException("订单已取消,无法继续流转");
}
@Override
public boolean canCancel() {
return false;
}
};
private final String description;
OrderStatus(String description) {
this.description = description;
}
public String getDescription() {
return description;
}
/**
* 获取下一个状态
*/
public abstract OrderStatus next();
/**
* 是否可以取消
*/
public abstract boolean canCancel();
/**
* 取消订单
*/
public OrderStatus cancel() {
if (!canCancel()) {
throw new IllegalStateException("当前状态不允许取消订单");
}
return CANCELLED;
}
}
/**
* 订单实体
*/
public class Order {
private String orderId;
private OrderStatus status;
public Order(String orderId) {
this.orderId = orderId;
this.status = OrderStatus.PENDING;
}
/**
* 流转到下一个状态
*/
public void moveToNext() {
System.out.println("订单 " + orderId + " 从 " + status.getDescription()
+ " 流转到 " + status.next().getDescription());
this.status = status.next();
}
/**
* 取消订单
*/
public void cancel() {
System.out.println("取消订单 " + orderId);
this.status = status.cancel();
}
public OrderStatus getStatus() {
return status;
}
}
// 使用示例
public class OrderDemo {
public static void main(String[] args) {
Order order = new Order("ORD001");
order.moveToNext(); // 待支付 -> 已支付
order.moveToNext(); // 已支付 -> 配送中
try {
order.cancel(); // 配送中不能取消
} catch (IllegalStateException e) {
System.out.println("错误: " + e.getMessage());
}
order.moveToNext(); // 配送中 -> 已送达
order.moveToNext(); // 已送达 -> 已完成
}
}案例 2:HTTP 响应状态码
java
/**
* HTTP 状态码枚举
*/
public enum HttpStatus {
// 2xx 成功
OK(200, "成功") {
@Override
public boolean isSuccess() {
return true;
}
},
CREATED(201, "已创建") {
@Override
public boolean isSuccess() {
return true;
}
},
// 4xx 客户端错误
BAD_REQUEST(400, "错误的请求") {
@Override
public boolean isClientError() {
return true;
}
},
UNAUTHORIZED(401, "未授权") {
@Override
public boolean isClientError() {
return true;
}
},
FORBIDDEN(403, "禁止访问") {
@Override
public boolean isClientError() {
return true;
}
},
NOT_FOUND(404, "未找到") {
@Override
public boolean isClientError() {
return true;
}
},
// 5xx 服务器错误
INTERNAL_SERVER_ERROR(500, "服务器内部错误") {
@Override
public boolean isServerError() {
return true;
}
},
SERVICE_UNAVAILABLE(503, "服务不可用") {
@Override
public boolean isServerError() {
return true;
}
};
private final int code;
private final String message;
private static final Map<Integer, HttpStatus> CODE_MAP = new HashMap<>();
static {
for (HttpStatus status : values()) {
CODE_MAP.put(status.code, status);
}
}
HttpStatus(int code, String message) {
this.code = code;
this.message = message;
}
public int getCode() {
return code;
}
public String getMessage() {
return message;
}
public boolean isSuccess() {
return false;
}
public boolean isClientError() {
return false;
}
public boolean isServerError() {
return false;
}
/**
* 根据状态码获取枚举
*/
public static HttpStatus fromCode(int code) {
HttpStatus status = CODE_MAP.get(code);
if (status == null) {
throw new IllegalArgumentException("未知的HTTP状态码: " + code);
}
return status;
}
/**
* 处理响应
*/
public void handleResponse() {
if (isSuccess()) {
System.out.println("请求成功: " + message);
} else if (isClientError()) {
System.out.println("客户端错误: " + message);
} else if (isServerError()) {
System.out.println("服务器错误: " + message);
}
}
}
// 使用示例
public class HttpDemo {
public static void main(String[] args) {
HttpStatus status = HttpStatus.fromCode(404);
status.handleResponse(); // 客户端错误: 未找到
if (status.isClientError()) {
System.out.println("需要检查请求参数");
}
}
}案例 3:权限验证
java
/**
* 用户角色枚举
*/
public enum UserRole {
ADMIN("管理员") {
@Override
public boolean hasPermission(String resource, String action) {
// 管理员拥有所有权限
return true;
}
},
MANAGER("经理") {
@Override
public boolean hasPermission(String resource, String action) {
// 经理可以查看和编辑,但不能删除
return "view".equals(action) || "edit".equals(action);
}
},
USER("普通用户") {
@Override
public boolean hasPermission(String resource, String action) {
// 普通用户只能查看
return "view".equals(action);
}
},
GUEST("访客") {
@Override
public boolean hasPermission(String resource, String action) {
// 访客只能查看公开资源
return "view".equals(action) && "public".equals(resource);
}
};
private final String description;
UserRole(String description) {
this.description = description;
}
public String getDescription(){
return description;
}
/**
* 检查权限
*/
public abstract boolean hasPermission(String resource, String action);
/**
* 执行操作
*/
public void performAction(String resource, String action) {
if (hasPermission(resource, action)) {
System.out.println(description + " 对 " + resource + " 执行 " + action + " 操作");
} else {
throw new SecurityException(description + " 没有权限执行此操作");
}
}
}
// 使用示例
public class PermissionDemo {
public static void main(String[] args) {
UserRole admin = UserRole.ADMIN;
UserRole user = UserRole.USER;
admin.performAction("document", "delete"); // 成功
try {
user.performAction("document", "delete"); // 抛出异常
} catch (SecurityException e) {
System.out.println("错误: " + e.getMessage());
}
}
}💡 最佳实践
1. 何时使用枚举替代 if-else
✅ 适合使用枚举的场景
java
// ✅ 固定的、有限的选项
public enum Season {
SPRING, SUMMER, AUTUMN, WINTER
}
// ✅ 状态机
public enum TrafficLight {
RED, YELLOW, GREEN
}
// ✅ 类型分类
public enum FileType {
PDF, DOCX, XLSX, JPG, PNG
}
// ✅ 配置选项
public enum LogLevel {
DEBUG, INFO, WARN, ERROR
}❌ 不适合使用枚举的场景
java
// ❌ 动态变化的值
// 不要用枚举表示用户ID、订单号等
// ❌ 数量不确定的选项
// 不要用枚举表示数据库中的动态分类
// ❌ 需要频繁修改的业务规则
// 考虑使用策略模式 + 配置文件2. 枚举设计原则
单一职责原则
java
// ✅ 好的设计:枚举只负责类型定义
public enum OrderType {
ONLINE, OFFLINE, WHOLESALE, RETAIL;
public String getDescription() {
return name();
}
}
// 处理逻辑放在专门的处理器中
public class OrderProcessor {
public void process(OrderType type) {
// 处理逻辑
}
}
// ❌ 不好的设计:枚举包含太多业务逻辑
public enum OrderType {
ONLINE {
public void process() {
// 大量业务逻辑...
// 数据库操作...
// 外部API调用...
}
}
}避免过度设计
java
// ✅ 简单场景用简单实现
public enum Status {
ACTIVE, INACTIVE;
public boolean isActive() {
return this == ACTIVE;
}
}
// ❌ 不要过度设计
public enum Status {
ACTIVE("激活", 1, true, "active") {
@Override
public void doSomething() {
// 复杂逻辑...
}
};
// 过多的字段和方法...
}3. 性能优化
使用 EnumSet 和 EnumMap
java
/**
* 使用 EnumSet 进行集合操作
*/
public class EnumSetDemo {
public enum Day {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}
public static void main(String[] args) {
// EnumSet 比 HashSet 更高效
EnumSet<Day> weekdays = EnumSet.range(Day.MONDAY, Day.FRIDAY);
EnumSet<Day> weekend = EnumSet.of(Day.SATURDAY, Day.SUNDAY);
System.out.println("工作日: " + weekdays);
System.out.println("周末: " + weekend);
}
}
/**
* 使用 EnumMap 进行映射
*/
public class EnumMapDemo {
public enum Color {
RED, GREEN, BLUE
}
public static void main(String[] args) {
// EnumMap 比 HashMap 更高效
EnumMap<Color, String> colorMap = new EnumMap<>(Color.class);
colorMap.put(Color.RED, "#FF0000");
colorMap.put(Color.GREEN, "#00FF00");
colorMap.put(Color.BLUE, "#0000FF");
System.out.println("红色代码: " + colorMap.get(Color.RED));
}
}缓存策略
java
/**
* 枚举中使用静态缓存
*/
public enum CachedEnum {
TYPE_A, TYPE_B, TYPE_C;
// 缓存计算结果
private static final Map<CachedEnum, String> CACHE = new EnumMap<>(CachedEnum.class);
static {
for (CachedEnum type : values()) {
CACHE.put(type, computeExpensiveValue(type));
}
}
private static String computeExpensiveValue(CachedEnum type) {
// 耗时计算
return "Computed value for " + type;
}
public String getCachedValue() {
return CACHE.get(this);
}
}4. 线程安全
java
/**
* 枚举天然线程安全
*/
public enum ThreadSafeSingleton {
INSTANCE;
private final AtomicInteger counter = new AtomicInteger(0);
public int incrementAndGet() {
return counter.incrementAndGet();
}
}
// 多线程环境下安全使用
public class ConcurrentDemo {
public static void main(String[] args) throws InterruptedException {
ExecutorService executor = Executors.newFixedThreadPool(10);
for (int i = 0; i < 100; i++) {
executor.submit(() -> {
int count = ThreadSafeSingleton.INSTANCE.incrementAndGet();
System.out.println("Count: " + count);
});
}
executor.shutdown();
executor.awaitTermination(1, TimeUnit.MINUTES);
}
}📊 对比总结
传统 if-else vs 枚举
| 维度 | if-else | 枚举 |
|---|---|---|
| 代码可读性 | ❌ 差 | ✅ 好 |
| 类型安全 | ❌ 无 | ✅ 有 |
| 编译检查 | ❌ 运行时错误 | ✅ 编译时检查 |
| 扩展性 | ❌ 难以扩展 | ✅ 易于扩展 |
| 维护成本 | ❌ 高 | ✅ 低 |
| 性能 | ✅ 略快 | ✅ 相当 |
| IDE支持 | ❌ 弱 | ✅ 强 |
代码行数对比
java
// 传统 if-else:50+ 行
public void processOrder(String type) {
if ("ONLINE".equals(type)) {
// 10行代码
} else if ("OFFLINE".equals(type)) {
// 10行代码
} else if ("WHOLESALE".equals(type)) {
// 10行代码
} else if ("RETAIL".equals(type)) {
// 10行代码
} else {
throw new IllegalArgumentException("未知类型");
}
}
// 枚举方案:1 行
public void processOrder(OrderType type) {
type.process(); // 逻辑封装在枚举中
}🎯 常见问题
Q1: 枚举可以继承吗?
答: 不可以。Java 中的枚举隐式继承自 java.lang.Enum,不能再继承其他类。但可以实现接口。
java
// ❌ 错误:枚举不能继承类
public enum MyEnum extends SomeClass { // 编译错误
}
// ✅ 正确:枚举可以实现接口
public enum MyEnum implements MyInterface {
INSTANCE;
@Override
public void method() {
// 实现接口方法
}
}Q2: 如何序列化枚举?
答: 枚举天然支持序列化,且保证单例特性。
java
public enum Status implements Serializable {
ACTIVE, INACTIVE;
}
// 序列化和反序列化后,仍然是同一个实例
Status original = Status.ACTIVE;
// 序列化...
// 反序列化...
Status deserialized = ...;
System.out.println(original == deserialized); // trueQ3: 枚举的性能如何?
答: 枚举的性能非常好:
java
// 1. 枚举比较使用 == 而不是 equals()
if (status == Status.ACTIVE) { // 非常快
}
// 2. switch 语句对枚举优化
switch (status) { // 编译器优化,使用跳转表
case ACTIVE: break;
case INACTIVE: break;
}
// 3. EnumSet 和 EnumMap 是专门优化的集合类
EnumSet<Day> set = EnumSet.of(Day.MONDAY); // 位向量实现,极快Q4: 枚举占用内存吗?
答: 枚举实例在类加载时创建,全局只有一份,内存占用很小。
java
public enum Color {
RED, GREEN, BLUE; // 只创建3个实例,全局共享
}📚 学习资源
官方文档
推荐阅读
- 《Effective Java》第三版 - Joshua Bloch
- 《Java核心技术》卷I - Cay S. Horstmann
- 《重构:改善既有代码的设计》- Martin Fowler
相关设计模式
- 策略模式:枚举 + 接口实现不同策略
- 状态模式:枚举表示不同状态及其行为
- 单例模式:枚举实现线程安全的单例
✅ 检查清单
在重构 if-else 为枚举之前,请检查:
- [ ] 选项是固定的、有限的
- [ ] 不会频繁增删选项
- [ ] 需要类型安全
- [ ] 需要更好的可读性和可维护性
- [ ] 每个选项有特定的行为或属性
- [ ] 希望利用编译时检查
🎓 总结
核心要点
- 类型安全:枚举提供编译时类型检查,避免字符串常量的拼写错误
- 代码简洁:将行为封装在枚举中,消除冗长的 if-else
- 易于维护:修改只需要在枚举类中进行,不影响使用方
- 性能优良:枚举比较使用 ==,switch 语句有编译器优化
- 功能强大:可以包含字段、方法、实现接口
实践建议
- 优先考虑枚举:当有固定选项时,首选枚举而非字符串或整数常量
- 封装行为:将相关行为封装在枚举中,而不是在调用方使用 switch
- 使用接口:当多个枚举有共同行为时,使用接口统一
- 合理设计:不要让枚举承担过多职责,保持单一职责原则
- 利用工具类:使用 EnumSet 和 EnumMap 提升性能
重构步骤
1. 识别 if-else 中的固定选项
2. 创建枚举类,定义所有选项
3. 为每个选项添加必要的属性和方法
4. 将原有的 if-else 逻辑迁移到枚举中
5. 修改调用方代码,使用枚举替代字符串
6. 测试验证功能正确性
7. 清理旧代码💻 完整示例代码
重构前
java
public class OrderServiceBefore {
public void processOrder(String orderType) {
if ("ONLINE".equals(orderType)) {
System.out.println("处理在线订单");
validateOnlinePayment();
sendEmail();
} else if ("OFFLINE".equals(orderType)) {
System.out.println("处理线下订单");
validateCash();
printReceipt();
} else if ("WHOLESALE".equals(orderType)) {
System.out.println("处理批发订单");
checkCredit();
generateInvoice();
} else {
throw new IllegalArgumentException("未知订单类型");
}
}
}重构后
java
public enum OrderType {
ONLINE("在线订单") {
@Override
public void process() {
System.out.println("处理" + getDescription());
validateOnlinePayment();
sendEmail();
}
},
OFFLINE("线下订单") {
@Override
public void process() {
System.out.println("处理" + getDescription());
validateCash();
printReceipt();
}
},
WHOLESALE("批发订单") {
@Override
public void process() {
System.out.println("处理" + getDescription());
checkCredit();
generateInvoice();
}
};
private final String description;
OrderType(String description) {
this.description = description;
}
public String getDescription() {
return description;
}
public abstract void process();
protected void validateOnlinePayment() {
System.out.println("验证在线支付");
}
protected void sendEmail() {
System.out.println("发送邮件");
}
protected void validateCash() {
System.out.println("验证现金");
}
protected void printReceipt() {
System.out.println("打印收据");
}
protected void checkCredit() {
System.out.println("检查信用");
}
protected void generateInvoice() {
System.out.println("生成发票");
}
}
public class OrderServiceAfter {
public void processOrder(OrderType orderType) {
orderType.process(); // 一行代码搞定!
}
}
// 使用示例
public class Main {
public static void main(String[] args) {
OrderServiceAfter service = new OrderServiceAfter();
// 类型安全,编译时检查
service.processOrder(OrderType.ONLINE);
service.processOrder(OrderType.WHOLESALE);
// service.processOrder("INVALID"); // 编译错误!
}
}🚀 下一步
识别项目中的 if-else 代码
- 使用 IDE 搜索功能查找长 if-else 链
- 关注业务逻辑中的类型判断
评估重构价值
- 判断选项是否固定
- 评估维护成本和收益
逐步重构
- 从简单场景开始
- 编写测试用例
- 渐进式替换
团队分享
- 分享重构经验
- 建立团队规范
- Code Review 中关注
最后更新:2025年
本文档持续更新中,欢迎提供反馈和建议。
