这篇聊聊策略模式, 策略模式(Strategy Pattern)是一种行为型设计模式 ,其主要目的是定义一系列算法,将每个算法封装起来,并使它们可以互换。策略模式允许客户端代码选择算法的具体实现,而不必与其直接耦合。这使得算法可以独立于客户端变化而变化。
策略模式就像是我们在玩电子游戏时选择角色的技能一样。我们的角色有不同的技能,而我们可以在游戏进行中根据需要选择使用哪个技能。这些技能就是策略,而我们的角色则是使用这些策略的客户端。
在程序设计中,策略模式的好处是,它使得算法的变化独立于使用算法的客户端。客户端只需知道如何选择合适的策略,而不需要关心策略的具体实现细节。这样,当需要添加新的策略时,可以方便地扩展系统,而不影响现有的代码。
策略模式提供了一种灵活的方法,使得算法可以根据需要动态地选择和切换,从而提高了系统的可维护性和可扩展性。
主要角色:
-
策略(Strategy): 定义了所有支持算法的共同接口,通常是一个接口或抽象类。
-
具体策略(Concrete Strategy): 实现了策略接口,提供了具体的算法实现。
-
上下文(Context): 维护一个对策略对象的引用,可以通过策略接口调用具体的算法。
示例:
举一个支付系统的例子,系统支持不同的支付方式,如信用卡支付、支付宝支付和微信支付,可以使用策略模式来实现。
java
// 策略接口
interface PaymentStrategy {
void pay(int amount);
}
// 具体策略 - 信用卡支付
class CreditCardPayment implements PaymentStrategy {
@Override
public void pay(int amount) {
System.out.println("Paid " + amount + " using Credit Card.");
}
}
// 具体策略 - 支付宝支付
class AlipayPayment implements PaymentStrategy {
@Override
public void pay(int amount) {
System.out.println("Paid " + amount + " using Alipay.");
}
}
// 具体策略 - 微信支付
class WeChatPayment implements PaymentStrategy {
@Override
public void pay(int amount) {
System.out.println("Paid " + amount + " using WeChat.");
}
}
// 上下文 - 支付服务
class PaymentService {
private PaymentStrategy paymentStrategy;
public void setPaymentStrategy(PaymentStrategy paymentStrategy) {
this.paymentStrategy = paymentStrategy;
}
public void processPayment(int amount) {
if (paymentStrategy != null) {
paymentStrategy.pay(amount);
} else {
System.out.println("No payment strategy set.");
}
}
}
// 客户端代码
public class Client {
public static void main(String[] args) {
PaymentService paymentService = new PaymentService();
// 选择信用卡支付策略
paymentService.setPaymentStrategy(new CreditCardPayment());
paymentService.processPayment(100);
// 切换到支付宝支付策略
paymentService.setPaymentStrategy(new AlipayPayment());
paymentService.processPayment(50);
// 切换到微信支付策略
paymentService.setPaymentStrategy(new WeChatPayment());
paymentService.processPayment(30);
}
}
在这个例子中,PaymentStrategy
是策略接口,定义了支付的行为。CreditCardPayment
、AlipayPayment
和 WeChatPayment
是具体策略,分别实现了信用卡支付、支付宝支付和微信支付的具体算法。PaymentService
是上下文,维护一个对策略对象的引用,并通过策略接口调用具体的支付算法。客户端代码可以通过设置不同的支付策略来选择不同的支付方式,而不必关心支付方式的具体实现。这使得系统更容易扩展,可以方便地添加新的支付方式,而不影响现有的客户端代码。
策略模式最好的地方就是可以消除贼多的if判断,若是一个类有多个条件语句来选择不同的行为,而这些条件语句可能随着时间的推移而变得复杂,策略模式可以用来替代这些条件语句。这样可以使代码更清晰、可维护性更高。
场景
再列举几个适用的场景:
- 多算法选择:当一个任务可以用多个算法解决,且在运行时需要灵活地选择其中一个算法时,策略模式就很适用。例如,排序算法可以有不同的实现(冒泡排序、快速排序等),根据具体需求选择不同的排序策略。
- 消除条件语句:当一个类有多个条件语句来选择不同的行为,而这些条件语句可能随着时间的推移而变得复杂,策略模式可以用来替代这些条件语句。这样可以使代码更清晰、可维护性更高。
- 动态配置:当需要动态地在运行时切换对象的行为,而且这些行为可以抽象为一系列算法时,策略模式是一个不错的选择。例如,一个电商网站可以根据用户的地理位置选择不同的运费计算策略。
- 算法族:当一组相关的算法形成一个算法族,可以将它们封装在一起,方便替换和扩展。策略模式允许新的算法被添加到系统中,而不影响现有的算法族。
- 避免使用条件判断:当不希望在代码中使用大量的条件判断语句,而希望通过一种更清晰、更可扩展的方式组织和管理算法时,策略模式是一个很好的选择。
策略模式适用于任何需要在运行时动态选择算法的情况,以及希望将算法的实现与客户端解耦的场景。
在我们的商城项目中不同的包裹根据实际情况需要派发给不同的快递,在打包的时候需要组合不同的参数,调不同的api。这里使用了策略模式。相对而言,策略模式还是比较好理解的一个设计模式。