策略模式(Strategy Pattern)是行为设计模式的一种,它定义了一系列算法,并将每一个算法封装起来,使它们可以互相替换,让算法的变化独立于使用算法的客户。策略模式让程序可以在运行时选择算法,灵活地改变程序的行为。
基本概念
策略接口:定义了所有支持的算法的公共接口。策略接口使得算法的变化不会影响到使用算法的客户。
具体策略类:实现了策略接口,封装了具体的算法实现。
上下文类(Context):维持一个对策略对象的引用,这个策略对象代表当前的算法。上下文类提供了调用策略接口的接口,以便在运行时可以切换策略。
核心要素
- Strategy(策略接口):定义所有支持的算法的公共操作接口。
- ConcreteStrategy(具体策略类):实现了Strategy接口,提供具体的算法实现。
- Context(上下文类):使用策略的类,维护一个Strategy对象的引用,并通过这个引用调用策略对象的算法。
优点
- 可扩展性:易于添加新的策略,只需要实现策略接口即可。
- 可维护性:算法的变更不会影响到使用算法的类,符合开闭原则。
- 代码复用:相同的策略可以在不同的上下文中重用。
- 灵活性:运行时决定使用哪种策略,提高了程序的灵活性。
应用场景
- 当有许多类似的类,它们之间的区别仅在于它们的行为(算法)不同时。
- 需要动态地在几种算法中选择一种时。
- 需要避免使用多重条件选择语句(如if...else或switch...case)来决定使用哪种算法时。
代码实现
以下是一个使用Java实现策略模式的简单示例,以购物车结算时应用不同会员等级折扣策略为例。
策略接口
public interface DiscountStrategy {
double calculateDiscount(double totalAmount);
}
具体策略类
普通会员折扣策略
public class NormalMemberDiscount implements DiscountStrategy {
@Override
public double calculateDiscount(double totalAmount) {
System.out.println("Applying discount for normal members.");
return totalAmount * 0.05; // 5% discount
}
}
银卡会员折扣策略
public class SilverMemberDiscount implements DiscountStrategy {
@Override
public double calculateDiscount(double totalAmount) {
System.out.println("Applying discount for silver members.");
return totalAmount * 0.10; // 10% discount
}
}
// 金卡、铂金卡等其他会员折扣策略的实现类省略...
上下文类(购物车)
public class ShoppingCart {
private double totalAmount;
private DiscountStrategy discountStrategy;
public ShoppingCart(double totalAmount) {
this.totalAmount = totalAmount;
this.discountStrategy = new NormalMemberDiscount(); // 默认为普通会员折扣
}
public void setDiscountStrategy(DiscountStrategy strategy) {
this.discountStrategy = strategy;
}
public double checkout() {
double discountAmount = discountStrategy.calculateDiscount(totalAmount);
double finalAmount = totalAmount - discountAmount;
System.out.println("Final amount after discount: " + finalAmount);
return finalAmount;
}
}
客户端代码
public class Client {
public static void main(String[] args) {
ShoppingCart cart = new ShoppingCart(100.0); // 假设购物车总金额为100元
cart.checkout(); // 使用默认的普通会员折扣
// 更改折扣策略为银卡会员
cart.setDiscountStrategy(new SilverMemberDiscount());
cart.checkout(); // 再次结账,应用银卡会员折扣
}
}
在这个例子中,DiscountStrategy
是策略接口,NormalMemberDiscount
、SilverMemberDiscount
等是具体策略类,而ShoppingCart
则是上下文类,负责在运行时选择并执行相应的折扣策略。客户端代码可以通过设置不同的策略来动态调整折扣计算方式,展示了策略模式的灵活性和可扩展性。