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 strategyMap = new ConcurrentHashMap<>(); // Spring 启动时自动注入所有策略 public PaymentStrategyFactory(List 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 实战,体现工程思维 > 就像阿策所说: > **"招式可换,心法不变。架构之道,亦在于此。"**

相关推荐
一定要AK8 分钟前
Spring 入门核心笔记
java·笔记·spring
A__tao9 分钟前
Elasticsearch Mapping 一键生成 Java 实体类(支持嵌套 + 自动过滤注释)
java·python·elasticsearch
KevinCyao22 分钟前
java视频短信接口怎么调用?SpringBoot集成视频短信及回调处理Demo
java·spring boot·音视频
科技小花23 分钟前
数据治理平台架构演进观察:AI原生设计如何重构企业数据管理范式
数据库·重构·架构·数据治理·ai-native·ai原生
迷藏49428 分钟前
**发散创新:基于Rust实现的开源合规权限管理框架设计与实践**在现代软件架构中,**权限控制(RBAC)** 已成为保障
java·开发语言·python·rust·开源
wuxinyan1232 小时前
Java面试题47:一文深入了解Nginx
java·nginx·面试题
新知图书2 小时前
搭建Spring Boot开发环境
java·spring boot·后端
冰河团队2 小时前
一个拉胯的分库分表方案有多绝望?整个部门都在救火!
java·高并发·分布式数据库·分库分表·高性能
洛_尘2 小时前
Java EE进阶:Linux的基本使用
java·java-ee
宸津-代码粉碎机2 小时前
Spring Boot 4.0虚拟线程实战调优技巧,最大化发挥并发优势
java·人工智能·spring boot·后端·python