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 实战,体现工程思维

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

相关推荐
西索斯coding10 分钟前
在 中接入 教程:p配置、m填写、扩展思考参数一篇就够(2)
java·前端·javascript·ai
隐退山林15 分钟前
JWT令牌技术
java·开发语言·java-ee
w_zero_one23 分钟前
动态规划(三)
java·算法·动态规划
木棉软糖34 分钟前
JDBC 读 ResultSet 读到一半,报 stream closed
java·mysql·spring
狂奔的sherry40 分钟前
JRuby 多线程反引号偶发 127:GC 提前释放了 posix_spawn 的 argv
java·linux·ruby·gc·jruby
咖啡八杯42 分钟前
异常体系设计:三类策略(i18n code、message、受检异常)
java·架构·代码规范
Spatial3Ddddd1 小时前
2026空间三维重建服务商横向对比
java·服务器·人工智能
Rain的Java大神之路1 小时前
Java 三层架构,90% 的人只答对一半:Controller 不是瘦,Service 不是透传,Dao 不是只写 SQL
java·后端·面试
Thomas.Sir1 小时前
第29课:微服务异步调用、线程池优化 & 事件驱动开发
java·redis·微服务
.Hypocritical.1 小时前
【Java 进阶】泛型深度解析|泛型类、泛型方法、通配符、类型擦除、PECS 原则
java·开发语言·泛型