策略模式(Strategy Pattern)是一种行为型设计模式,它允许你定义一系列算法或行为,并将它们封装成独立的类,使得它们在运行时可以互相替换。这样做的好处是解耦算法与使用它的上下文对象,提高系统的灵活性和可扩展性。
一、核心思想
定义一组算法,把它们分别封装起来,使它们可以互换使用。 通俗地说: 把“做什么”和“怎么做”分开; 上下文(Context)不关心具体怎么执行,只关心有一个接口可以调用; 具体的行为由不同的策略类实现。
核心概念
- 策略接口(Strategy Interface):定义了所有支持的算法的公共操作。
- 具体策略类(Concrete Strategies):实现了接口中的具体算法。
- 上下文类(Context Class):使用某个策略来完成特定的任务,它不关心具体的策略实现,只通过接口调用算法。
二、 示例代码结构
以一个支付系统为例,我们可以为不同的支付方式(如支付宝、微信、信用卡等)实现策略模式:
1. 定义策略接口 PaymentStrategy.java
public interface PaymentStrategy {
void pay(int amount);
}
2. 实现具体策略类
- AlipayStrategy.java
public class AlipayStrategy implements PaymentStrategy {
@Override
public void pay(int amount) {
System.out.println("通过支付宝支付: " + amount + "元");
}
}
- WeChatPayStrategy.java
public class WeChatPayStrategy implements PaymentStrategy {
@Override
public void pay(int amount) {
System.out.println("通过微信支付: " + amount + "元");
}
}
- CreditCardStrategy.java
public class CreditCardStrategy implements PaymentStrategy {
@Override
public void pay(int amount) {
System.out.println("通过信用卡支付: " + amount + "元");
}
}
3. 上下文类 PaymentContext.java
public class PaymentContext {
private PaymentStrategy strategy;
public void setPaymentStrategy(PaymentStrategy strategy) {
this.strategy = strategy;
}
public void executePayment(int amount) {
strategy.pay(amount);
}
}
4. 主程序 Main.java
public class Main {
public static void main(String[] args) {
PaymentContext context = new PaymentContext();
// 使用支付宝支付
context.setPaymentStrategy(new AlipayStrategy());
context.executePayment(100);
// 切换为微信支付
context.setPaymentStrategy(new WeChatPayStrategy());
context.executePayment(200);
// 切换为信用卡支付
context.setPaymentStrategy(new CreditCardStrategy());
context.executePayment(300);
}
}
运行结果
通过支付宝支付: 100元
通过微信支付: 200元
通过信用卡支付: 300元
三、优缺点
优点
- 解耦:客户端无需知道具体策略的实现细节,只需选择合适的策略即可。
- 扩展性强:新增一种策略只需要添加一个新的具体策略类,不需要修改已有代码。
- 易于切换:运行时可以动态地切换策略。
缺点:
- 类爆炸风险 策略较多时,类数量会增加
- 客户端需要了解策略 客户端必须知道所有策略类才能选择
- 不适合简单逻辑 如果策略之间差异不大,使用策略模式反而复杂化代码
四、Spring 中的应用场景举例
在 Spring 中,策略模式也被广泛使用,比如: 场景 示例 ResourceLoader 加载资源时支持不同协议(file://, classpath:// 等) MessageSource 国际化消息处理策略 PlatformTransactionManager 支持不同事务管理器(JDBC、Hibernate、JPA 等) BeanNameUrlHandlerMapping / SimpleUrlHandlerMapping 控制器映射策略 自定义策略 如订单处理、促销规则、日志输出等