定义
策略模式是行为型设计模式之一,它定义了一系列的算法,并将每个算法封装起来,而且还使他们还可以相互替换。这样就可以让算法区别于使用它的客户而产生变化。
简单来讲就是:针对同一类型的多种处理方式,仅仅是具体行为有差别。即,具有同类可替代的行为逻辑算法场景会进行使用,例如:
1. 不同类型的交易方式(信用卡、支付宝、微信)
2. 生成唯一ID策略(UUID、DB自增、DB+Redis、雪花算法、Leaf算法)
这些都可以通过策略模式进行行为包装,提供给外部使用。
策略模式的实现构成
构成
1. 策略接口(Strategy Interface):定义了所有支持的算法的公共接口。策略接口使得算法可以互换。
2. 具体策略类(Concrete Strategy Classes):实现了策略接口,每个类都提供了一种具体的算法实现。
3. 上下文类(Context Class):持有一个策略接口的引用,给客户端调用,用来操作策略的环境。上下文类可以设置具体策略,并通过策略接口调用算法。它隔离了客户端与具体策略的实现细节。
UML图
策略模式的代码实现
场景
假设你正在设计一个购物系统,用户可以选择不同的支付策略(如信用卡支付、支付宝支付、微信支付等)。
在这里,“支付方式”就可以作为一个策略模式的应用场景,我们定义一个支付策略接口,然后为每种支付方式创建一个具体策略类,而购物系统的上下文类则根据用户的支付选择来使用相应的支付策略。
这样的话,当我们需要添加新的支付方式时,只需增加一个新的策略类,而无需修改现有代码。
代码实现
策略接口// 支付策略接口,定义了一个支付方法,所有具体的支付策略都需要实现这个接口。
interface PaymentStrategy {
void pay(double amount);
}
具体策略类
// 信用卡支付策略的具体实现类
class CreditCardPaymentStrategy implements PaymentStrategy {
private String cardNumber;
private String cardHolderName;
public CreditCardPaymentStrategy(String cardNumber, String cardHolderName) {
this.cardNumber = cardNumber;
this.cardHolderName = cardHolderName;
}
@Override
public void pay(double amount) {
// 实际的信用卡支付逻辑
System.out.println("使用信用卡支付:" + amount + " 元");
System.out.println("卡号: " + cardNumber + ", 持卡人: " + cardHolderName);
}
}
// 支付宝支付策略的具体实现类
class AlipayPaymentStrategy implements PaymentStrategy {
private String alipayAccount;
public AlipayPaymentStrategy(String alipayAccount) {
this.alipayAccount = alipayAccount;
}
@Override
public void pay(double amount) {
// 实际的支付宝支付逻辑
System.out.println("使用支付宝支付:" + amount + " 元");
System.out.println("支付宝账号: " + alipayAccount);
}
}
// 微信支付策略的具体实现类
class WeChatPaymentStrategy implements PaymentStrategy {
private String weChatId;
public WeChatPaymentStrategy(String weChatId) {
this.weChatId = weChatId;
}
@Override
public void pay(double amount) {
// 实际的微信支付逻辑
System.out.println("使用微信支付:" + amount + " 元");
System.out.println("微信ID: " + weChatId);
}
}
上下文类
// 购物上下文类,使用支付策略来进行支付
class ShoppingCart {
private PaymentStrategy paymentStrategy;
// 设置支付策略
public void setPaymentStrategy(PaymentStrategy paymentStrategy) {
this.paymentStrategy = paymentStrategy;
}
// 执行支付
public void checkout(double amount) {
if (paymentStrategy == null) {
throw new IllegalStateException("支付策略未设置");
}
paymentStrategy.pay(amount);
}
}
客户端代码
public class StrategyPatternDemo {
public static void main(String[] args) {
// 创建购物车对象
ShoppingCart cart = new ShoppingCart();
// 用户选择信用卡支付
cart.setPaymentStrategy(new CreditCardPaymentStrategy("1234-5678-9012-3456", "张三"));
cart.checkout(500.00);
System.out.println();
// 用户选择支付宝支付
cart.setPaymentStrategy(new AlipayPaymentStrategy("zhangsan@alipay.com"));
cart.checkout(300.00);
System.out.println();
// 用户选择微信支付
cart.setPaymentStrategy(new WeChatPaymentStrategy("zhangsan123"));
cart.checkout(200.00);
}
}
总结
优点
1. 算法的封装:每个算法都被封装在自己的类中,使得它易于修改和切换,提高代码的复用性。
2. 可扩展性:易于增加新的策略,无须修改原有代码,符合开闭原则。
3. 提高代码可读性和维护性:通过将算法的实现与使用算法的代码分离,使得代码结构更加清晰。
缺点
1. 客户端必须知道所有策略类,并自行决定使用哪种策略。
2. 每个具体策略都需要一个单独的类来实现,因此如果策略很多,可能会导致产生很多策略类。
应用场景
1. 当有多种相似的行为,而客户端需要根据情况选择使用其中一种的时候。
2. 需要动态地在几种算法中切换时候,那么可以采用。
3. 避免使用多重条件判断来决定使用哪种算法的情况,以减少代码的复杂度和提高可维护性。
其他设计模式文章:
- 设计模式 - Singleton pattern 单例模式
- 设计模式 - Factory Method 工厂方法
- 设计模式 - Chain Of Responsibility 责任链模式
- 设计模式 - Template Method 模板方法
- 设计模式 - Strategy Pattern策略模式
- 设计模式 - Observer Pattern 观察者模式
最后
如果小伙伴们觉得我写的文章不错的话,那么请给我点点关注,我们下次见!