Java设计模式漫画英雄宇宙之策略模式:从支付系统重构到软考高频考点(附完整代码 + 面试高频问法)

🎭 一、漫画开场:小贾的"支付之痛"

小贾是一个刚接手电商系统的新晋 Java 工程师。某天,产品经理跑来:"咱们要支持微信、支付宝、银联、京东支付、Apple Pay,而且未来可能还要加数字货币!"

他翻开支付模块,看到这样的代码:

java 复制代码
public void pay(String payType, double amount) {
    if ("wechat".equals(payType)) {
        // 微信支付逻辑
    } else if ("alipay".equals(payType)) {
        // 支付宝逻辑
    } else if ("unionpay".equals(payType)) {
        // 银联逻辑
    } 
    // ......未来还要加更多 if-else
}public void pay(String payType, double amount) {
    if ("wechat".equals(payType)) {
        // 微信支付逻辑
    } else if ("alipay".equals(payType)) {
        // 支付宝逻辑
    } else if ("unionpay".equals(payType)) {
        // 银联逻辑
    } 
    // ......未来还要加更多 if-else
}

"这哪是代码,这是技术债炸弹!"小贾哀嚎。

这时,神秘高人策略大师·阿策 闪现:"年轻人,你需要------策略模式(Strategy Pattern)!"

🔍 二、策略模式:定义与核心思想

GoF 定义

定义一系列算法,将每一个算法封装起来,并使它们可以互相替换。策略模式让算法的变化独立于使用它的客户端。
核心思想
将"变"与"不变"分离

  • 不变:支付流程(下单 → 选择方式 → 调用支付 → 返回结果)
  • 变:具体支付实现(微信、支付宝等)
    属于行为型设计模式 ,软考高级架构师考试中属于高频考点(尤其在"系统设计"和"代码重构"题型中)。

🏗️ 三、策略模式的三大角色(UML + 代码实现)

1. UML 类图(建议保存)

2. 完整 Java 代码实现(可直接复制运行)

java 复制代码
// 1. 策略接口:支付行为抽象
public interface PaymentStrategy {
    void pay(double amount);
}

// 2. 具体策略实现
public class WeChatPay implements PaymentStrategy {
    @Override
    public void pay(double amount) {
        System.out.println("[微信支付] 扫码完成,支付金额:" + amount + " 元");
    }
}

public class Alipay implements PaymentStrategy {
    @Override
    public void pay(double amount) {
        System.out.println("[支付宝] 指纹验证通过,支付金额:" + amount + " 元");
    }
}

public class UnionPay implements PaymentStrategy {
    @Override
    public void pay(double amount) {
        System.out.println("[银联支付] 刷卡成功,支付金额:" + amount + " 元");
    }
}

// 3. 上下文:持有策略并执行
public class PaymentContext {
    private PaymentStrategy strategy;

    public void setPaymentStrategy(PaymentStrategy strategy) {
        this.strategy = strategy;
    }

    public void executePayment(double amount) {
        if (strategy == null) {
            throw new IllegalStateException("未设置支付策略!");
        }
        strategy.pay(amount);
    }
}

3. 客户端调用示例

java 复制代码
public class Main {
    public static void main(String[] args) {
        PaymentContext context = new PaymentContext();

        // 用户选择微信支付
        context.setPaymentStrategy(new WeChatPay());
        context.executePayment(99.9);

        // 用户切换为支付宝
        context.setPaymentStrategy(new Alipay());
        context.executePayment(199.0);
    }
}

✅ 输出:

微信支付 扫码完成,支付金额:99.9 元

支付宝 指纹验证通过,支付金额:199.0 元

🚀 四、进阶实战:策略 + 工厂 + 注解,打造企业级支付引擎

实际项目中,我们不会手动 new WeChatPay(),而是用策略工厂 + 注解自动注册,提升扩展性。

1. 定义支付类型枚举

java 复制代码
public enum PayType {
    WECHAT, ALIPAY, UNIONPAY
}

2. 添加策略标识注解

java 复制代码
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface PayStrategy {
    PayType value();
}

3. 策略类加上注解

java 复制代码
@PayStrategy(PayType.WECHAT)
public class WeChatPay implements PaymentStrategy { ... }

@PayStrategy(PayType.ALIPAY)
public class Alipay implements PaymentStrategy { ... }

4. 策略工厂(Spring 环境下可用 ApplicationContext 获取 Bean)

java 复制代码
@Component
public class PaymentStrategyFactory {

    private final Map<PayType, PaymentStrategy> strategyMap = new ConcurrentHashMap<>();

    // Spring 启动时自动注入所有策略
    public PaymentStrategyFactory(List<PaymentStrategy> strategies) {
        for (PaymentStrategy strategy : strategies) {
            PayStrategy annotation = strategy.getClass().getAnnotation(PayStrategy.class);
            if (annotation != null) {
                strategyMap.put(annotation.value(), strategy);
            }
        }
    }

    public PaymentStrategy getStrategy(PayType type) {
        PaymentStrategy strategy = strategyMap.get(type);
        if (strategy == null) {
            throw new IllegalArgumentException("不支持的支付方式: " + type);
        }
        return strategy;
    }
}

5. 服务层调用

java 复制代码
@Service
public class OrderService {

    @Autowired
    private PaymentStrategyFactory factory;

    public void pay(PayType type, double amount) {
        PaymentStrategy strategy = factory.getStrategy(type);
        strategy.pay(amount);
    }
}

✅ 优势:

  • 新增支付方式?只需写一个带注解的类,零修改
  • 符合 开闭原则(OCP),软考/面试高频加分项!

🧠 五、策略模式 vs 其他模式(面试高频对比)

对比项 策略模式 状态模式 模板方法
目的 封装可互换算法 对象行为随状态变化 定义算法骨架,子类实现步骤
客户端是否感知 是(主动切换策略) 否(状态自动切换) 否(调用固定模板)
类图结构 Context 持有 Strategy Context 与 State 双向依赖 抽象类 + 子类
典型场景 支付方式、排序算法 订单状态机(待支付→已支付→已发货) 数据处理流程(读→处理→写)

✅ 六、总结:为什么你必须掌握策略模式?

  1. 解决 if-else 膨胀:让代码从"面条"变"模块"
  2. 提升系统可扩展性:新增功能不改旧代码,符合架构师核心能力
  3. 软考高频考点:行为型模式代表,论文/案例分析常客
  4. 面试加分项:能结合工厂、注解、Spring 实战,体现工程思维

就像阿策所说:
"招式可换,心法不变。架构之道,亦在于此。"

相关推荐
二月夜1 小时前
剖析Java正则表达式回溯问题
java·正则表达式
xuhaoyu_cpp_java2 小时前
项目学习(三)分页查询
java·经验分享·笔记·学习
程序员二叉2 小时前
【Java】集合面试全套精讲|HashMap/ArrayList高频考点完整版
java·面试·哈希算法
cfm_29143 小时前
JVM GC垃圾回收初步了解
java·开发语言·jvm
心之伊始3 小时前
LangChain4j RAG 实战:Java 后端如何把本地文档接入 Embedding 检索链路
java·架构·源码分析·csdn
许彰午3 小时前
17_synchronized关键字深度解析
java·开发语言
Xzh04235 小时前
AI Agent 学习路线(Java 后端方向)
java·人工智能·学习
艾利克斯冰5 小时前
Java 设计模式-行为型模式(更新中)
java·开发语言·设计模式
倒霉蛋小马5 小时前
Java新特性:record关键字
java·开发语言
折哥的程序人生 · 物流技术专研6 小时前
《Java 100 天进阶之路》第95篇:消息队列基础(RocketMQ/Kafka)(2026版)
java·面试·kafka·rocketmq·java-rocketmq·求职招聘