策略模式(Strategy Pattern)是一种行为设计模式,它定义了一系列算法或策略,并将每个算法封装在独立的类中,使得它们可以互相替换。策略模式的核心思想是将算法的使用与算法的实现解耦,这样可以在不影响客户端代码的情况下更改或扩展算法。
策略模式的关键角色
- 策略接口(Strategy Interface):定义了所有支持的算法的公共接口。这个接口不是必须的,但通常会有一个接口来规范所有具体策略的行为。
- 具体策略类(Concrete Strategy Classes):实现了策略接口所定义的算法。
- 上下文类(Context Class):持有一个对策略对象的引用,并通过该引用来调用具体的策略方法。
示例场景
假设我们正在开发一个支付系统,用户可以选择不同的支付方式,如信用卡支付、PayPal支付等。我们可以为每种支付方式创建一个具体策略类,然后根据用户的偏好动态选择合适的策略。
Java 实现策略模式的例子
首先,定义一个策略接口 PaymentStrategy
,它声明了一个支付方法 pay
:
// PaymentStrategy.java
public interface PaymentStrategy {
void pay(int amount);
}
接下来,实现几种具体的支付策略:
// CreditCardPayment.java
public class CreditCardPayment implements PaymentStrategy {
private String cardNumber;
public CreditCardPayment(String cardNumber) {
this.cardNumber = cardNumber;
}
@Override
public void pay(int amount) {
System.out.println(amount + " paid using credit/debit card number: " + cardNumber);
}
}
// PayPalPayment.java
public class PayPalPayment implements PaymentStrategy {
private String emailId;
public PayPalPayment(String emailId) {
this.emailId = emailId;
}
@Override
public void pay(int amount) {
System.out.println(amount + " paid using PayPal account: " + emailId);
}
}
然后,定义一个上下文类 ShoppingCart
,它使用一个 PaymentStrategy
来执行支付操作:
// ShoppingCart.java
public class ShoppingCart {
private PaymentStrategy paymentStrategy;
public void setPaymentStrategy(PaymentStrategy paymentStrategy) {
this.paymentStrategy = paymentStrategy;
}
public void checkout(int amount) {
if (paymentStrategy == null) {
throw new IllegalStateException("Payment strategy not set");
}
paymentStrategy.pay(amount);
}
}
最后,客户端代码可以根据需要设置不同的支付策略并完成支付:
// Main.java
public class Main {
public static void main(String[] args) {
ShoppingCart cart = new ShoppingCart();
// 使用信用卡支付
PaymentStrategy creditCardPayment = new CreditCardPayment("1234-5678-9012-3456");
cart.setPaymentStrategy(creditCardPayment);
cart.checkout(100);
// 使用PayPal支付
PaymentStrategy payPalPayment = new PayPalPayment("user@example.com");
cart.setPaymentStrategy(payPalPayment);
cart.checkout(200);
}
}
这段代码展示了如何利用策略模式来实现不同支付方式的选择。通过这种方式,我们可以轻松地添加新的支付方式而不需要修改现有的代码,这符合开闭原则(Open/Closed Principle)。此外,策略模式还简化了单元测试,因为每个策略都可以单独进行测试。