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 实战,体现工程思维 > 就像阿策所说: > **"招式可换,心法不变。架构之道,亦在于此。"**

相关推荐
z***43844 小时前
java与mysql连接 使用mysql-connector-java连接msql
java·开发语言·mysql
白露与泡影4 小时前
大厂Java面试前复习的正确姿势(800+面试题附答案解析)
java·开发语言·面试
N***p3654 小时前
Springboot项目中线程池使用整理
java·spring boot·后端
asom224 小时前
互联网大厂Java全栈面试故事:从Spring Boot、分布式到AI业务场景深度剖析
java·spring boot·分布式·缓存·微服务·消息队列·面试经验
程序定小飞4 小时前
基于SpringBoot+Vue的常规应急物资管理系统的设计与实现
java·开发语言·vue.js·spring boot·后端·spring
t梧桐树t4 小时前
spring AI都能做什么
java·人工智能·spring
R***z1014 小时前
Spring容器初始化扩展点:ApplicationContextInitializer
java·后端·spring
好好研究4 小时前
SSM整合(一)
java·spring·mvc·mybatis·db
口袋物联5 小时前
设计模式之单例模式在 C 语言中的应用(含 Linux 内核实例)
c语言·单例模式·设计模式
tgethe5 小时前
Lambda表达式
java·后端