策略模式
策略模式(Strategy Pattern)是一种行为设计模式,它允许你在运行时根据需要定义一系列算法,将每个算法封装起来,并使它们可以相互替换。策略模式将算法的使用与算法的实现分离开来,从而让算法的变化不会影响到使用算法的客户端代码。
应用场景
策略模式适用于以下场景:
- 当你需要在一个类中定义多种行为,并且这些行为可以在运行时改变时。
- 当你有许多相似的类,它们之间的唯一区别在于它们的行为时。
- 当你需要将算法的实现与算法的使用分离开来时。
结构
策略模式主要由以下几部分组成:
- 上下文(Context):持有对一个策略对象的引用,并定义一个接口让策略对象可以访问它的数据。
- 策略接口(Strategy Interface):定义所有支持的算法的公共接口。
- 具体策略(Concrete Strategies):实现策略接口的具体算法。
- 客户端(Client):创建并配置上下文对象,并选择一个具体的策略对象传递给上下文。
优点
- 灵活性和可扩展性:策略模式允许你在运行时选择算法,从而可以很容易地添加新的算法或修改现有的算法。
- 封装性:每个算法都被封装在自己的类中,减少了代码的复杂性。
- 可复用性:策略模式鼓励算法的复用。
- 易于理解和维护:策略模式将算法的实现与使用分离开来,使得代码更易于理解和维护。
缺点
- 客户端必须知道所有的策略类:客户端需要了解所有的策略类,并选择合适的策略传递给上下文。
- 策略类会增多:每当你需要添加一个新的算法时,都需要创建一个新的策略类。
示例
假设我们正在开发一个购物车应用程序,我们需要根据不同的支付方式计算总价。我们可以使用策略模式来实现这一功能。
首先,我们定义一个支付策略接口:
public interface PaymentStrategy {
void pay(double amount);
}
然后,我们实现具体的支付策略:
public class CreditCardStrategy implements PaymentStrategy {
public void pay(double amount) {
System.out.println("Pay using Credit Card: $" + amount);
}
}
public class PayPalStrategy implements PaymentStrategy {
public void pay(double amount) {
System.out.println("Pay using PayPal: $" + amount);
}
}
接下来,我们创建一个购物车上下文:
public class ShoppingCart {
private PaymentStrategy paymentStrategy;
public void setPaymentStrategy(PaymentStrategy paymentStrategy) {
this.paymentStrategy = paymentStrategy;
}
public void checkout(double amount) {
paymentStrategy.pay(amount);
}
}
最后,客户端代码可以如下所示:
public class Client {
public static void main(String[] args) {
ShoppingCart cart = new ShoppingCart();
cart.setPaymentStrategy(new CreditCardStrategy());
cart.checkout(100);
cart.setPaymentStrategy(new PayPalStrategy());
cart.checkout(200);
}
}
在这个例子中,我们首先使用信用卡支付100美元,然后使用PayPal支付200美元。通过使用策略模式,我们可以很容易地添加新的支付方式,而不需要修改购物车类。