Java中枚举可天然实现策略模式,每个枚举实例封装行为与状态,支持抽象方法、构造参数、函数式接口及安全查找,使策略即实例、即配置、即执行者,更简洁内聚。

Java 中可以通过枚举(enum)天然实现策略模式,因为枚举实例本身就是单例、线程安全、不可变的,并且能直接封装行为逻辑——比传统策略接口 + 多个实现类更简洁、更内聚。
枚举自带策略方法:每个实例定义自己的行为
在枚举中为每个常量实现统一的抽象方法(如 execute()),让不同枚举值持有各自的具体逻辑。这样调用方只需根据业务类型获取对应枚举,再调用方法即可,无需 if-else 或工厂类。
示例:支付方式策略
public enum PaymentStrategy {
ALIPAY {
@Override
public void pay(Order order) {
System.out.println("使用支付宝支付:" + order.getAmount());
}
},
WECHAT_PAY {
@Override
public void pay(Order order) {
System.out.println("使用微信支付:" + order.getAmount());
}
},
BANK_TRANSFER {
@Override
public void pay(Order order) {
System.out.println("使用银行转账支付:" + order.getAmount());
}
};
public abstract void pay(Order order);
}
使用时:
PaymentStrategy.WECHAT_PAY.pay(order);
支持构造参数和内部状态:增强策略灵活性
枚举可以带私有字段和构造器,适合需要配置参数的策略(比如不同折扣率、API 地址、超时时间等)。
示例:通知渠道策略(含渠道编码和重试次数)
public enum NotifyChannel {
SMS("sms", 2),
EMAIL("email", 1),
PUSH("push", 3);
private final String code;
private final int maxRetry;
NotifyChannel(String code, int maxRetry) {
this.code = code;
this.maxRetry = maxRetry;
}
public void send(String content) {
System.out.printf("通过 %s 发送通知(最多重试 %d 次):%s%n", code, maxRetry, content);
}
public String getCode() { return code; }
public int getMaxRetry() { return maxRetry; }
}
结合函数式接口:用 lambda 简化策略定义(Java 8+)
如果策略逻辑简单,可让枚举持有一个函数式接口实例(如 Consumer, Function),避免重复写抽象方法。
示例:日志级别处理器
public enum LogLevel {
DEBUG(msg -> System.out.println("[DEBUG] " + msg)),
INFO(msg -> System.out.println("[INFO] " + msg)),
ERROR(msg -> System.err.println("[ERROR] " + msg));
private final Consumer<string> handler;
LogLevel(Consumer<string> handler) {
this.handler = handler;
}
public void log(String message) {
handler.accept(message);
}
}</string></string>
安全获取策略:避免空指针,推荐用静态方法封装查找逻辑
不要直接用 Enum.valueOf()(抛异常),建议在枚举内提供容错的查找方法,比如按字符串或 code 匹配。
- 添加静态
fromCode(String)方法,返回Optional或默认策略 - 内部用
Stream.of(values()).filter(...).findFirst()查找(适合 code 不唯一或需复杂匹配) - 若 code 是唯一标识,可用
Map预加载提升性能(在 static 块中初始化)
示例:
public enum DiscountType {
SEASONAL(0.15),
MEMBER(0.2),
COUPON(0.3);
private final double rate;
private static final Map<string discounttype> LOOKUP = Arrays.stream(values())
.collect(Collectors.toMap(e -> e.name().toLowerCase(), Function.identity()));
DiscountType(double rate) { this.rate = rate; }
public double getRate() { return rate; }
public static Optional<discounttype> fromName(String name) {
return Optional.ofNullable(LOOKUP.get(name != null ? name.toLowerCase() : ""));
}
}</discounttype></string>
不复杂但容易忽略:枚举策略的本质是“行为 + 数据”的合一,它让策略即实例、即配置、即执行者,代码更紧凑,维护更集中。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











