策略模式说明
策略模式是一种行为设计模式,它使你能在运行时改变对象的行为。这种模式定义了一系列可互换的算法,并将每个算法封装在自己的类里。这些算法以相同的方式声明,因此客户端可以使用相同的接口调用不同的算法。
优点
- 它将算法的使用与算法的实现分离开来。
- 支持开闭原则:可以在不修改原有代码的情况下添加新的策略。
缺点
- 如果可用的策略数量很多,那么可能会导致大量的策略类。
- 客户端必须了解各个策略的区别并自行决定使用哪一个。
策略模式组成
- 环境(Context):这个类通常包含一个对策略对象的引用,并且有一个方法来让策略对象执行它的行为。
- 策略接口(Strategy Interface):定义了一个公共接口,所有支持的策略都需要实现这个接口。
- 具体策略(Concrete Strategies):实现了策略接口,并提供了具体的算法实现。
策略模式 Demo 演示
根据上面的策略模式组成,编写环境、策略接口、具体策略
策略接口(Strategy Interface)
/**
* 策略接口
*
* @since 2024/07/13
**/
public interface Strategy {
public int doOperation(int num1, int num2);
}
具体策略(Concrete Strategies)
减法策略
/**
* 减法策略
* @since 2024/07/13
**/
public class OperationSubtract implements Strategy {
@Override
public int doOperation(int num1, int num2) {
return num1 - num2;
}
}
加法策略
/**
* 加法策略
* @since 2024/07/13
**/
public class OperationAdd implements Strategy {
@Override
public int doOperation(int num1, int num2) {
return num1 + num2;
}
}
环境(Context)
/**
* 上下文
*
* @since 2024/07/13
**/
public class Context {
private Strategy strategy;
public Context(Strategy strategy){
this.strategy = strategy;
}
public int executeStrategy(int num1, int num2){
return strategy.doOperation(num1, num2);
}
}
运用场景演示
/**
* 策略模式,实际运用场景演示
*
* @since 2024/07/13
**/
public class StrategyPatternDemo {
public static void main(String[] args) {
// 设置加法操作
Context context = new Context(new OperationAdd());
System.out.println("10 + 5 = " + context.executeStrategy(10, 5));
// 设置减法操作
context = new Context(new OperationSubtract());
System.out.println("10 - 5 = " + context.executeStrategy(10, 5));
}
}
个人理解
1.定义Strategy
策略接口,然后根据不同的策略类,实现该策略接口;
2.Context
环境类,这里通过带参构造函数方式,要求传入策略接口。这里因为 Java 的多态性,即子类对象可以当作其父类(策略接口)来使用,可以根据需要传入OperationAdd
实现类或者OperationSubtract
实现类。所以Context
环境类能够在不知道具体实现细节的情况下使用不同的策略实现。这便是策略模式的优势之一:可以在运行时动态的选择和更换算法实现。
策略模式在 Spring 中应用
当然可以。在Spring框架中,策略模式的应用非常常见,因为它可以帮助我们实现更为灵活和解耦的代码结构。下面我将展示一个简单的例子,说明如何在Spring项目中使用策略模式。
假设我们正在开发一个电商应用,我们需要处理不同类型的订单支付(如信用卡支付、支付宝支付、微信支付等)。我们可以使用策略模式来实现支付方式的选择。
第一步:定义策略接口
首先,我们需要定义一个策略接口,这里我们叫做 PaymentStrategy
:
public interface PaymentStrategy {
void pay(int amount);
}
第二步:实现不同的策略
接下来,我们需要为每一种支付方式实现这个接口:
@Service("creditCardPayment")
public class CreditCardPayment implements PaymentStrategy {
@Override
public void pay(int amount) {
System.out.println(amount + " paid with credit/debit card");
}
}
@Service("alipayPayment")
public class AlipayPayment implements PaymentStrategy {
@Override
public void pay(int amount) {
System.out.println(amount + " paid with Alipay");
}
}
@Service("wechatPayment")
public class WechatPayment implements PaymentStrategy {
@Override
public void pay(int amount) {
System.out.println(amount + " paid with WeChat Pay");
}
}
这里我们使用了@Service
注解,这样Spring就可以管理这些策略类,并且可以根据名称注入特定的支付策略。
第三步:定义上下文
为了选择合适的支付策略,我们需要定义一个上下文类,它会根据用户的输入选择正确的策略:
public class PaymentContext {
private PaymentStrategy strategy;
public PaymentContext(PaymentStrategy strategy) {
this.strategy = strategy;
}
public void setStrategy(PaymentStrategy strategy) {
this.strategy = strategy;
}
public void executeStrategy(int amount) {
strategy.pay(amount);
}
}
第四步:使用策略
最后,我们可以通过注入不同的策略来使用这些支付方式:
@Controller
public class OrderController {
@Autowired
private Map<String, PaymentStrategy> paymentStrategies;
@GetMapping("/pay")
public String pay(@RequestParam("amount") int amount, @RequestParam("paymentMethod") String paymentMethod) {
PaymentStrategy strategy = paymentStrategies.get(paymentMethod);
PaymentContext context = new PaymentContext(strategy);
context.executeStrategy(amount);
return "redirect:/order/confirmation";
}
}
在这个例子中,OrderController
控制器接收一个支付金额 (amount
) 和一个支付方式 (paymentMethod
)。然后从 paymentStrategies
中获取对应的策略,并通过 PaymentContext
执行支付逻辑。
注释
- 使用
@Service
和@Autowired
以及Map
类型的注入,我们可以轻松地管理多个策略实例,并且可以动态地选择使用哪一个策略。 OrderController
中的paymentStrategies
是一个由Spring自动填充的Map
,键是策略类的别名(@Service
注解中的值),值则是策略实例本身。- 用户可以通过 URL 参数来选择支付方式。
这就是在Spring项目中使用策略模式的一个简单示例。这种方法能够让我们更容易地扩展和维护支付逻辑,同时也使得代码更加清晰和模块化。
PS:
如果你看到这里,希望我的分享,可以帮到你,感谢你的阅读,愿我们在代码世界变得更强!