策略模式由三个核心角色组成:
- 环境(Context)角色:持有一个策略对象的引用,用于调用具体的算法。
- 抽象策略(Strategy)角色:定义了一个公共接口,所有具体策略类都要实现这个接口。
- 具体策略(Concrete Strategy)角色:实现了抽象策略定义的接口,提供具体的算法实现。
策略模式的优点有:
- 算法的变化独立于使用它的客户端,客户端可以根据需要选择不同的算法,而不需要修改代码。
- 策略类之间可以自由切换,增加、删除或替换策略类都不会影响客户端的代码。
- 策略模式提供了一种简单的扩展方式,可以通过增加新的策略类来扩展系统的功能。
策略模式的缺点有:
- 客户端需要了解所有的策略类,并自行选择合适的策略类,增加了客户端的复杂性。
- 策略模式增加了系统中的类和对象的数量,可能会导致系统更加庞大。
下面以一个商场促销的例子来说明策略模式的应用。
假设一个商场需要实现不同的促销策略,比如打折、满减等。首先,定义一个抽象的促销策略接口 PromotionStrategy
,它包含一个用于计算实际价格的方法。
public interface PromotionStrategy { double calculatePrice(double price); }
然后,定义具体的促销策略类,如打折策略和满减策略。
public class DiscountStrategy implements PromotionStrategy { private double discount; public DiscountStrategy(double discount) { this.discount = discount; } public double calculatePrice(double price) { return price * discount; } } public class FullReductionStrategy implements PromotionStrategy { private double threshold; private double reduction; public FullReductionStrategy(double threshold, double reduction) { this.threshold = threshold; this.reduction = reduction; } public double calculatePrice(double price) { if (price >= threshold) { return price - reduction; } else { return price; } } }
接下来,定义一个商场类 ShoppingMall
,它持有一个促销策略对象,并提供一个用于计算实际价格的方法。
public class ShoppingMall { private PromotionStrategy promotionStrategy; public void setPromotionStrategy(PromotionStrategy promotionStrategy) { this.promotionStrategy = promotionStrategy; } public double calculatePrice(double price) { if (promotionStrategy != null) { return promotionStrategy.calculatePrice(price); } else { return price; } } }
使用策略模式的客户端代码如下:
public class Client { public static void main(String[] args) { ShoppingMall shoppingMall = new ShoppingMall(); PromotionStrategy discountStrategy = new DiscountStrategy(0.8); shoppingMall.setPromotionStrategy(discountStrategy); double price1 = shoppingMall.calculatePrice(100); System.out.println("The actual price is " + price1); PromotionStrategy fullReductionStrategy = new FullReductionStrategy(200, 50); shoppingMall.setPromotionStrategy(fullReductionStrategy); double price2 = shoppingMall.calculatePrice(300); System.out.println("The actual price is " + price2); } }
运行上述代码,输出结果如下:
The actual price is 80.0 The actual price is 250.0
从上述示例可以看出,策略模式通过将算法封装到具体的策略类中,使得算法的变化独立于使用它的客户端。客户端只需要选择合适的策略类,无需关心具体的算法实现。这样可以提高代码的灵活性和可维护性。
总结来说,策略模式是一种行为型设计模式,它通过将算法封装到具体的策略类中,使得算法的变化独立于使用它的客户端。策略模式适用于需要在运行时根据不同的条件选择不同的算法的情况。