策略模式(Strategy Pattern)是一种行为设计模式,它定义了一系列算法,并将每一个算法封装起来,使它们可以互换。策略模式使得算法可以独立于使用它的客户端而变化。
主要角色
-
策略接口(Strategy):
- 这是一个抽象类或接口,定义了所有支持的算法的公共接口。
- 上下文使用这个接口来调用算法。
-
具体策略(Concrete Strategy):
- 实现了策略接口的具体算法。
- 具体策略类提供了具体的算法实现,并且可以被上下文使用。
-
上下文(Context):
- 持有一个策略接口的引用。
- 客户端通过上下文来调用算法。上下文在运行时可以动态地改变策略对象,从而改变算法。
示例代码
以下是一个简单的策略模式示例,用于计算不同折扣策略下的价格。
// 策略接口
interface DiscountStrategy {
double calculateDiscount(double price);
}
// 具体策略:无折扣
class NoDiscountStrategy implements DiscountStrategy {
@Override
public double calculateDiscount(double price) {
return price;
}
}
// 具体策略:百分比折扣
class PercentageDiscountStrategy implements DiscountStrategy {
private double percentage;
public PercentageDiscountStrategy(double percentage) {
this.percentage = percentage;
}
@Override
public double calculateDiscount(double price) {
return price * (1 - percentage / 100);
}
}
// 具体策略:固定金额折扣
class FixedAmountDiscountStrategy implements DiscountStrategy {
private double amount;
public FixedAmountDiscountStrategy(double amount) {
this.amount = amount;
}
@Override
public double calculateDiscount(double price) {
return price - amount;
}
}
// 上下文
class ShoppingCart {
private DiscountStrategy discountStrategy;
public ShoppingCart(DiscountStrategy discountStrategy) {
this.discountStrategy = discountStrategy;
}
public void setDiscountStrategy(DiscountStrategy discountStrategy) {
this.discountStrategy = discountStrategy;
}
public double calculateTotal(double price) {
return discountStrategy.calculateDiscount(price);
}
}
// 客户端代码
public class StrategyPatternDemo {
public static void main(String[] args) {
double price = 100.0;
ShoppingCart cart = new ShoppingCart(new NoDiscountStrategy());
System.out.println("Total price with no discount: " + cart.calculateTotal(price));
cart.setDiscountStrategy(new PercentageDiscountStrategy(10));
System.out.println("Total price with 10% discount: " + cart.calculateTotal(price));
cart.setDiscountStrategy(new FixedAmountDiscountStrategy(15));
System.out.println("Total price with $15 discount: " + cart.calculateTotal(price));
}
}
优点
- 算法自由切换:策略模式使得算法可以独立于使用它的客户端而变化。
- 扩展性好:通过增加新的策略类,可以很容易地扩展系统。
- 避免多重条件判断:使用策略模式可以避免在客户端代码中使用多重条件判断来选择算法。
缺点
- 策略类数量增加:当策略数量较多时,会增加类的数量,从而增加系统的复杂性。
- 客户端需要了解策略:客户端需要知道有哪些策略可供选择,并了解如何创建和配置这些策略对象。
适用场景
- 当有多种算法需要实现,并且这些算法可以互换时。
- 当算法在运行时需要动态地改变时。
- 当算法的实现需要隐藏,或者算法的实现细节对客户端不可见时。
策略模式是一种非常灵活的设计模式,适用于需要动态选择算法的场景。通过封装算法,策略模式使得算法的变化不会影响到使用它的客户端代码。