枚举策略模式实战:优雅消除支付场景的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);
    }
}

适用场景

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

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

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

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

相关推荐
nice_lcj5208 分钟前
ThreadLocal 入门:它是怎么隔离数据的、为什么会导致内存泄漏
java·开发语言·后端·面试·并发编程·内存泄漏·threadlocal
紧跟先前的步伐20 分钟前
Go AI Agent 实战 28|Agent 的预算、超时与停止条件
开发语言·人工智能·后端·ai·golang
秋天的怀念_David23 分钟前
算法一千零一夜 · 第二十六夜 协议的母语
java·spring boot·算法
灿飞23 分钟前
Kotlin与Java虚拟机八:控制流与 when:卫语句、上下文相关解析与穷尽性
java·kotlin
文丑颜不良啊1 小时前
LeetCode2021~2040题目解析
java·leetcode
bksczm1 小时前
InnoDB 行格式详解:DYNAMIC / COMPACT / COMPRESSED / REDUNDANT
java·开发语言·数据库
春涧草茶2 小时前
慢就是快16-1协程
开发语言·前端·python
liangbo72 小时前
Spring系列03:Bean 的三种注册方式
java·spring
余槐i2 小时前
MySQL 8.0 联合索引走错:为什么加了索引查询反而从 200ms 变成 8s
java·spring boot·mysql·docker·性能优化
SL_staff2 小时前
制造业订单交付总在最后一刻爆雷?用结构化计划模板打通跨系统协同断点
java·开源·全栈