在软件开发中,面对同一问题往往存在多种解决方案,且这些方案可能需要根据不同场景动态切换。策略模式为这种场景提供了优雅的解决方案,它能让算法或行为在不影响客户端的情况下灵活替换。
策略模式是一种行为型设计模式,其核心思想是定义一系列算法,将每个算法封装起来,并使它们可以相互替换,让算法的变化独立于使用算法的客户端。简单来说,策略模式就是把做一件事的不同方法(策略)分开封装,使得这些方法可以互相替换,而且更换方法的时候不会影响到使用这些方法的代码。例如,在电商平台的结算系统中,用户可能会使用不同的支付方式,如支付宝支付、微信支付、银行卡支付等。这些支付方式都是完成支付这一功能的不同策略,使用策略模式,我们可以把每种支付方式封装成一个独立的策略类,结算系统在需要支付时,只需根据用户选择的支付方式切换相应的策略即可,无需修改结算系统的核心代码。
策略模式的核心原理是通过抽象出一个策略接口,让具体的策略类实现该接口,再通过一个上下文类来引用策略接口,从而实现策略的动态切换。策略模式的结构主要包含以下几个部分:
(1)抽象策略角色):定义了所有具体策略类共有的接口,声明了具体策略类需要实现的方法,是策略模式的核心抽象。
(2)具体策略角色:实现了抽象策略角色所定义的接口,包含了具体的算法或行为。
(3)上下文角色:持有一个抽象策略角色的引用,负责与具体策略类交互。客户端通过上下文类来使用策略,上下文类可以动态地切换不同的具体策略。
通过这样的结构,客户端只需与上下文类交互,无需直接接触具体策略类,当需要更换策略时,只需更换上下文类中引用的具体策略对象即可,实现了算法与客户端的解耦。
策略模式在系统设计中有着重要的作用,主要体现在以下几个方面:
(1)实现算法的切换自由:客户端可以根据需求在运行时动态切换不同的策略,无需修改原有代码,提高了系统的灵活性。
(2)避免多重条件判断:如果不使用策略模式,往往需要通过多重 if-else 或 switch-case 语句来选择不同的算法,使用策略模式后,可以将这些判断逻辑移除,代之以策略的动态切换,使代码更加清晰、易于维护。
(3)实现开闭原则:当需要添加新的策略时,只需新增一个实现抽象策略接口的具体策略类,无需修改现有代码,符合开闭原则。
(4)提高代码复用性:将不同的算法封装在独立的策略类中,这些策略类可以在不同的场景中被复用。
策略模式的优点主要有:
(1)灵活性高:策略模式使得算法可以独立于客户端而变化,客户端可以根据需要灵活地选择和切换策略,适应不同的业务场景。
(2)代码结构清晰:将不同的算法封装在不同的策略类中,避免了多重条件判断语句,使代码结构更加清晰,易于理解和维护。
(3)符合开闭原则:新增策略时,只需添加新的具体策略类,无需修改原有代码,降低了系统的维护成本。
(3)可扩展性强:可以方便地扩展新的策略,满足不断变化的业务需求。
而其缺点主要有:
(1)客户端需要了解所有策略:客户端必须知道所有的具体策略类,并理解它们之间的区别,才能选择合适的策略,这增加了客户端的使用难度。
(2)策略类数量可能过多:如果系统中存在很多种策略,会导致策略类的数量急剧增加,增加了系统的复杂性。
(3)策略类之间无法共享数据:每个策略类都是独立的,它们之间不能直接共享数据,若需要共享数据,可能需要引入额外的机制。
下面以电商平台的支付系统为例来演示策略模式的实现。支付系统中有多种支付方式(如支付宝支付、微信支付),我们通过策略模式让客户端可以动态选择不同的支付方式。
// 支付策略接口(抽象策略角色)
interface PaymentStrategy {
// 支付方法
void pay(double amount);
}
// 支付宝支付(具体策略角色)
class AlipayStrategy implements PaymentStrategy {
private String account;
public AlipayStrategy(String account) {
this.account = account;
}
@Override
public void pay(double amount) {
System.out.println("使用支付宝账号 " + account + " 支付了 " + amount + " 元");
}
}
// 微信支付(具体策略角色)
class WechatPayStrategy implements PaymentStrategy {
private String wechatId;
public WechatPayStrategy(String wechatId) {
this.wechatId = wechatId;
}
@Override
public void pay(double amount) {
System.out.println("使用微信账号 " + wechatId + " 支付了 " + amount + " 元");
}
}
// 支付上下文(上下文角色)
class PaymentContext {
private PaymentStrategy paymentStrategy;
// 设置支付策略
public void setPaymentStrategy(PaymentStrategy paymentStrategy) {
this.paymentStrategy = paymentStrategy;
}
// 调用策略的支付方法
public void pay(double amount) {
if (paymentStrategy != null) {
paymentStrategy.pay(amount);
} else {
System.out.println("请选择支付方式");
}
}
}
// 客户端
public class Client {
public static void main(String[] args) {
// 创建支付上下文
PaymentContext paymentContext = new PaymentContext();
// 选择支付宝支付
paymentContext.setPaymentStrategy(new AlipayStrategy("zhangsan@alipay.com"));
paymentContext.pay(100.0);
// 切换为微信支付
paymentContext.setPaymentStrategy(new WechatPayStrategy("wx123456789"));
paymentContext.pay(200.0);
}
}
其运行结果为:
使用支付宝账号 zhangsan@alipay.com 支付了 100.0 元
使用微信账号 wx123456789 支付了 200.0 元