枚举常量本身即可作为策略对象直接使用,无需容器或工厂类;每个枚举项实现抽象方法(如execute),支持多态调用、编译期校验与IDE补全,变量名即引用,零开销且类型安全。

可以直接用枚举常量本身作为算法对象,无需额外容器或工厂类——因为每个枚举实例天然就是策略的实现体,变量名(如 PayStrategy.ALIPAY)即对应可执行的算法对象。
定义带抽象行为的枚举策略
在枚举类中声明抽象方法,强制每个常量提供具体实现。这样枚举值不只是名字,而是具备执行能力的对象。
- 用 abstract 关键字定义统一接口,例如
execute(PaymentContext ctx) - 每个枚举项在花括号内重写该方法,注入专属逻辑(如调用支付宝 SDK、微信统一下单)
- 不依赖 new 或反射,
ALIPAY.execute(ctx)就是直接调用,语义清晰、类型安全
通过变量名获取并使用策略对象
Java 编译后,枚举常量是静态不可变的全局单例,可通过类名加点号直取,无需查找、缓存或转换。
-
PayStrategy strategy = PayStrategy.WECHAT;—— 变量名即引用,零开销 -
strategy.execute(context);—— 直接触发多态行为,无 if-else 分支 - 支持 IDE 自动补全、编译期校验,拼错变量名(如
WECHT)直接报错
补充按业务字段反查的静态方法(非必需但实用)
若需从外部输入(如字符串 "alipay")动态获取策略对象,可在枚举中添加静态查找方法,内部用 Map 缓存提升性能。
- 声明
private static final Map<string paystrategy> BY_CODE = new HashMap();</string> - 在静态块中预热:
Arrays.stream(values()).forEach(s -> BY_CODE.put(s.code, s)); - 提供语义化方法:
public static PayStrategy fromCode(String code) { return BY_CODE.getOrDefault(code, DEFAULT); } - 注意:这仅用于动态场景;“变量名直取”仍是首选,更轻量、更可靠
避免常见误区
不要把枚举当配置中心或字符串映射表来用——它的核心价值在于“命名即实例”。
- 不用
Enum.valueOf("ALIPAY"),那是为反射准备的,易抛异常且失去类型提示 - 不建议让枚举持有策略类 Class 对象再 newInstance(),绕过编译检查,破坏枚举行为内聚性
- 不推荐在业务层再包一层 StrategyFactory,徒增间接性,违背枚举策略“即取即用”的设计初衷

















