当if else比较多时候应该怎么避免?
当代码中出现大量 if-else
分支时,不仅可读性和可维护性变差,还容易引发逻辑错误。为了解决这个问题,可以采用以下几种 替代方案:
✅ 1. 使用策略模式(Strategy Pattern)
适合:分支是“行为”的不同实现。
public interface DiscountStrategy {double calculatePrice(double price);
}public class VipDiscount implements DiscountStrategy {public double calculatePrice(double price) {return price * 0.8;}
}public class NormalDiscount implements DiscountStrategy {public double calculatePrice(double price) {return price;}
}
public class PriceCalculator {private static final Map<String, DiscountStrategy> strategyMap = Map.of("VIP", new VipDiscount(),"NORMAL", new NormalDiscount());public double calculate(String userType, double price) {return strategyMap.getOrDefault(userType, new NormalDiscount()).calculatePrice(price);}
}
✅ 2. 使用 Map + 函数式接口(推荐 Java 8+)
适合:简单的逻辑映射。
Map<String, Runnable> actionMap = new HashMap<>();
actionMap.put("A", () -> System.out.println("执行 A"));
actionMap.put("B", () -> System.out.println("执行 B"));String type = "A";
actionMap.getOrDefault(type, () -> System.out.println("默认操作")).run();
✅ 3. 枚举 + 多态
📌 适用场景:
- 条件分支基于有限个明确的状态值(如订单状态、角色类型等)。
- 每个状态对应一个明确的行为逻辑。
✅ 示例:订单状态处理
public enum OrderStatus {NEW {@Overridepublic void handle() {System.out.println("处理新订单逻辑");}},PAID {@Overridepublic void handle() {System.out.println("处理已支付订单逻辑");}},SHIPPED {@Overridepublic void handle() {System.out.println("处理已发货订单逻辑");}};public abstract void handle();
}
🧠 使用方式:
public class OrderService {public void process(OrderStatus status) {status.handle();}
}
✅ 优点:
- 避免冗长的 if-else。
- 新增状态只需新增一个枚举项,不改原代码,符合开闭原则。
- 每个状态的行为直接定义在枚举里,聚合了状态与行为,代码更清晰。
❗注意事项:
- 不适用于状态行为较复杂或状态不确定的场景。
- 枚举内部代码不要太复杂,保持简洁。
✅ 4. 使用工厂模式(Factory Pattern)
适合:根据条件返回不同对象的场景。
public interface Handler {void handle();
}public class TypeAHandler implements Handler {public void handle() {System.out.println("处理A类型");}
}
public class HandlerFactory {private static final Map<String, Handler> map = Map.of("A", new TypeAHandler()// add more);public static Handler getHandler(String type) {return map.get(type);}
}
✅ 5. 使用责任链模式(Chain of Responsibility)
📌 适用场景:
- 多个判断条件需要依次执行,类似流水线。
- 每个处理逻辑可以选择“处理或不处理”,并交给下一个。
- 比如日志过滤、请求校验、审批流程。
✅ 类图结构(简化):
Handler(抽象处理者)├── setNext(Handler)└── handle(Request)↓ConcreteHandlerA
ConcreteHandlerB
...
✅ 示例:审批流程
public abstract class Approver {protected Approver next;public void setNext(Approver next) {this.next = next;}public abstract void approve(int amount);
}
public class Manager extends Approver {public void approve(int amount) {if (amount <= 1000) {System.out.println("Manager approved " + amount);} else if (next != null) {next.approve(amount);}}
}public class Director extends Approver {public void approve(int amount) {if (amount <= 5000) {System.out.println("Director approved " + amount);} else if (next != null) {next.approve(amount);}}
}
// 使用:
Approver manager = new Manager();
Approver director = new Director();
manager.setNext(director);manager.approve(800); // Manager approved
manager.approve(3000); // Director approved
✅ 优点:
- 解耦请求与处理者,请求发出者不关心处理逻辑。
- 易于扩展,新增处理者只需加一环节。
- 逻辑清晰,便于流程控制(可以中止传递)。
❗注意事项:
- 如果链过长,性能会受影响。
- 某些环节不处理也不传递,会造成请求丢失,要小心设计。
✅ 6. 表驱动法(适用于数学或规则匹配)
适合:根据输入查表返回结果(用二维数组或 Map)。
🛑 不推荐做法(陷阱)
if (type.equals("A")) { ... }
else if (type.equals("B")) { ... }
// 太多时会越来越难维护
✅ 总结:选型建议
适用场景 | 推荐方案 |
---|---|
行为多变,结构清晰 | 策略模式、责任链模式 |
简单条件分支 | Map + Lambda |
固定类型对应行为 | 枚举 + 多态 |
条件逻辑可抽象成对象工厂 | 工厂模式 |
条件判断涉及顺序或权限依赖 | 责任链模式 |
我们来详细讲讲你感兴趣的两种方法:枚举 + 多态 和 责任链模式。这两种都是在“if-else
太多”时非常实用的重构技巧,各有适用场景。