策略模式是一种行为型设计模式,它通过定义一系列算法,并将每个算法封装到独立的类中,使得它们可以相互替换使用,从而使算法的变化可独立于使用它的客户端而变化。
在策略模式中,有三个角色:
-
环境类(Context):维护一个对抽象策略类的引用,并调用该策略对象的方法。
-
抽象策略类(Strategy):定义一个接口,用于封装具体算法的实现。
-
具体策略类(Concrete Strategy):实现抽象策略类中的方法,提供特定算法的具体实现。
下面通过代码样例来说明策略模式。
假设现在有一个支付系统,有不同的支付渠道,比如支付宝、微信、银联等。我们需要让系统调用不同的支付渠道进行支付,而不希望针对每个支付渠道写一个不同的支付方法。这个问题可以通过策略模式来解决。
首先我们定义一个抽象策略类 PayStrategy,它定义了一个 pay 方法,用于具体的支付实现:
public interface PayStrategy {
void pay(BigDecimal totalPrice);
}
然后定义不同的具体策略类 PayByAlipay、PayByWeChat 和 PayByUnionpay,用于具体实现不同的支付逻辑:
public class PayByAlipay implements PayStrategy {
@Override
public void pay(BigDecimal totalPrice) {
System.out.println("Pay " + totalPrice + " by Alipay.");
}
}
public class PayByWeChat implements PayStrategy {
@Override
public void pay(BigDecimal totalPrice) {
System.out.println("Pay " + totalPrice + " by WeChat.");
}
}
public class PayByUnionpay implements PayStrategy {
@Override
public void pay(BigDecimal totalPrice) {
System.out.println("Pay " + totalPrice + " by Unionpay.");
}
}
接下来定义环境类 PayContext,它包含了一个 PayStrategy 对象,并调用该对象的 pay 方法:
public class PayContext {
private PayStrategy payStrategy;
public PayContext(PayStrategy payStrategy) {
this.payStrategy = payStrategy;
}
public void pay(BigDecimal totalPrice) {
payStrategy.pay(totalPrice);
}
}
最后,我们可以通过实例化不同的具体策略类来使用不同的支付渠道进行支付:
public class App {
public static void main(String[] args) {
BigDecimal totalPrice = new BigDecimal("100.00");
PayContext payContext;
// 使用支付宝支付
payContext = new PayContext(new PayByAlipay());
payContext.pay(totalPrice);
// 使用微信支付
payContext = new PayContext(new PayByWeChat());
payContext.pay(totalPrice);
// 使用银联支付
payContext = new PayContext(new PayByUnionpay());
payContext.pay(totalPrice);
}
}
这样,我们可以在不修改系统逻辑的情况下,轻松切换支付渠道。从而实现了代码的可扩展性和可维护性。
总结:
策略模式通过定义一系列算法,并将每个算法封装到独立的类中,使得它们可以相互替换使用,从而使算法的变化可独立于使用它的客户端而变化。在实际开发中,我们可以通过策略模式来避免大量的 if-else 嵌套,提高代码的可读性、可扩展性和可维护性。
策略模式是一种常用的设计模式,它可以用于解决许多不同领域的问题。下面是策略模式的一些常见应用场景:
- 排序算法
在排序算法中,我们可以使用策略模式来实现不同的排序算法。比如,在Java中,Collections.sort()方法接受一个Comparator对象,这个对象用来定义比较两个元素的顺序,通过传入不同的Comparator实现类,就可以实现不同的排序算法。
- 游戏 AI
在游戏 AI 中,我们可以使用策略模式来实现不同的 AI 策略。比如,在一个跑酷游戏中,我们可以定义多个 AI 策略,如“跳绳子”、“上跳板”、“攀爬”等,然后根据不同的环境和人物状态,选择相应的策略来实现游戏 AI。
- 媒体播放器
在媒体播放器中,我们可以使用策略模式来实现不同的播放方式。比如,在一个音乐播放器中,我们可以定义多个播放策略,如“单曲循环”、“顺序播放”、“列表循环”等,然后根据用户的选择,选择相应的播放策略来实现不同的播放方式。
- 网络请求库
在网络请求库中,我们可以使用策略模式来实现不同的请求方式。比如,在一个网络请求库中,我们可以定义多个请求策略,如“GET 请求”、“POST 请求”、“PUT 请求”等,然后根据不同的请求方式,选择相应的策略来实现网络请求。
- 日志记录
在日志记录中,我们可以使用策略模式来实现不同的日志记录方式。比如,在一个日志记录系统中,我们可以定义多个日志记录策略,如“控制台输出”、“文件输出”、“邮件输出”等,然后根据不同的日志记录方式,选择相应的策略来实现日志记录。
总之,策略模式可以应用于许多不同的领域和场景,它的优点是灵活、可扩展、易于维护,可以让代码具有更好的可读性和可重用性。