枚举策略模式实战:优雅消除支付场景的if-else

在支付场景中使用枚举实现策略模式,可以优雅地消除if-else语句,提高代码的可读性、可维护性和扩展性。以下是具体实现方案:

1. 定义策略枚举

java 复制代码
@Getter
@RequiredArgsConstructor
public enum PaymentStrategy {
    ALIPAY(1, "支付宝") {
        @Override
        public void processPayment(BigDecimal amount) {
            System.out.println("支付宝支付: " + amount + "元");
            // 调用支付宝SDK的具体逻辑
        }
    },
    WECHAT_PAY(2, "微信支付") {
        @Override
        public void processPayment(BigDecimal amount) {
            System.out.println("微信支付: " + amount + "元");
            // 调用微信支付SDK的具体逻辑
        }
    },
    CREDIT_CARD(3, "信用卡支付") {
        @Override
        public void processPayment(BigDecimal amount) {
            System.out.println("信用卡支付: " + amount + "元");
            // 调用银行API的逻辑
        }
    };

    /**
     * 编码
     */
    private final Integer code;
    /**
     * 说明
     */
    private final String desc;

    /**
     * 抽象支付方法(策略接口)
     * @param amount 支付金额
     */
    public abstract void processPayment(BigDecimal amount);
}

2. 上下文处理器(消除 if-else)

java 复制代码
public class PaymentProcessor {
    public void executePayment(String paymentType, BigDecimal amount) {
        // 通过枚举名直接获取策略(无需条件判断)
        PaymentStrategy strategy = PaymentStrategy.valueOf(paymentType.toUpperCase());
        strategy.processPayment(amount);
    }
}

3. 客户端调用

java 复制代码
public class Client {
    public static void main(String[] args) {
        PaymentProcessor processor = new PaymentProcessor();

        // 直接通过支付类型字符串调用(无if-else)
        processor.executePayment("ALIPAY", new BigDecimal("100.50"));
        processor.executePayment("WECHAT_PAY", new BigDecimal("200.00"));
    }
}

优势分析

  1. 消除条件判断:

    • 直接通过valueOf()将字符串映射到枚举策略,彻底消除if-else/switch
  2. 开闭原则:

    java 复制代码
    // 扩展新支付方式只需添加枚举常量
    PaymentStrategy.BANK_TRANSFER {
        @Override
        public void processPayment(BigDecimal amount) {
            System.out.println("银行转账: " + amount);
        }
    };

    新增策略时 无需修改已有代码,符合开放-封闭原则

  3. 强类型约束:

    • 编译器会强制要求每个枚举实现策略方法

    • 避免字符串拼写错误(IllegalArgumentException)

  4. 策略集中管理:

    • 所有策略在枚举中一目了然

    • 天然的单例保证(无需考虑线程安全问题)

处理非法支付类型

java 复制代码
public void executePayment(String paymentType, BigDecimal amount) {
    try {
        PaymentStrategy strategy = PaymentStrategy.valueOf(paymentType.toUpperCase());
        strategy.processPayment(amount);
    } catch (IllegalArgumentException e) {
        // 统一处理未知支付类型
        throw new UnsupportedPaymentTypeException("不支持的支付方式: " + paymentType);
    }
}

适用场景

  • 策略类型固定且有限(如支付方式、状态机)

  • 需要强类型约束和编译期检查

  • 策略本身无需复杂状态维护

对比传统工厂模式:枚举策略模式更简洁,但扩展性略低于类层次结构实现。适合策略数量可控的场景,若策略行为过于复杂或需要动态加载,建议采用传统接口+实现类的方式。

相关推荐
小羊没烦恼!4 天前
微服务化的基石——持续集成
java·大数据·word·powerpoint·.net
俊昭喜喜里4 天前
java中的继承和多态的区别
java
小羊没烦恼!4 天前
初探性能优化——2个月到4小时的性能提升
java·开发语言·windows·算法·c#
譕痕4 天前
JSONObject与JSONArray封装数据格式区别
java·json
胡写代码4 天前
别再前后端各写一套表单校验了
java·后端
小鱼能吃糖4 天前
缺陷修复总览 · mall电商项目:5类缺陷,1个病根,4个业务域
java·电商
此时不提桶,更待何时4 天前
01-06-A-JVM排查实战详解
java·jvm
伞伞悦读4 天前
【第38期】Python 模块与包详解:import、from、模块搜索路径、包结构和 __init__
开发语言·python
vipxieliang4 天前
ValidX 在 DDD 领域驱动设计中的实践
java·spring boot
C语言小火车4 天前
C/C++ 为什么需要编译器?
开发语言·c++