目录
策略模式(Strategy Pattern)是一种行为型设计模式,它定义了一系列的算法,并将每一个算法封装起来,使它们可以相互替换。策略模式让算法的变化独立于使用算法的客户。这种模式涉及三个主要角色:
- 策略接口(Strategy Interface):定义了一个算法的接口,或者说定义了所有支持的算法的公共接口。
- 具体策略类(Concrete Strategy):实现了策略接口的类。具体策略类封装了实现了算法的细节。
- 上下文(Context):接受客户的请求,随后把请求委托给一个或多个策略对象,由它们来执行算法。上下文维护对策略对象的引用,并可在运行时动态地改变这个引用,以改变算法的执行。
优点
- 算法自由切换:可以在运行时切换对象内部的算法,从而改变对象的行为。
- 简化单元测试:每个算法都有自己的类,可以通过自己的接口单独测试。
- 符合开闭原则:对扩展开放,对修改关闭,可以轻松扩展新的算法类。
缺点
- 策略类会增多:当策略过多时,会导致类数目庞大,增加了系统的复杂度。
- 客户端必须了解所有策略:客户端必须知道所有的策略类,以便决定使用哪一个策略。
示例
假设我们有一个系统,需要根据用户的不同等级应用不同的折扣策略。
策略接口(Strategy Interface):
public interface DiscountStrategy {
double calculateDiscount(double originalPrice);
}
具体策略类(Concrete Strategy):
public class NormalDiscountStrategy implements DiscountStrategy {
@Override
public double calculateDiscount(double originalPrice) {
return originalPrice * 0.95; // 95折
}
}
public class MemberDiscountStrategy implements DiscountStrategy {
@Override
public double calculateDiscount(double originalPrice) {
return originalPrice * 0.9; // 9折
}
}
上下文(Context):
public class DiscountContext {
private DiscountStrategy strategy;
public DiscountContext(DiscountStrategy strategy) {
this.strategy = strategy;
}
public void setStrategy(DiscountStrategy strategy) {
this.strategy = strategy;
}
public double calculateFinalPrice(double originalPrice) {
return strategy.calculateDiscount(originalPrice);
}
}
客户端代码:
public class Client {
public static void main(String[] args) {
DiscountContext context = new DiscountContext(new NormalDiscountStrategy());
double finalPrice = context.calculateFinalPrice(100.0);
System.out.println("Final Price with Normal Discount: " + finalPrice);
context.setStrategy(new MemberDiscountStrategy());
finalPrice = context.calculateFinalPrice(100.0);
System.out.println("Final Price with Member Discount: " + finalPrice);
}
}
在这个例子中,我们定义了两种不同的折扣策略(普通折扣和会员折扣),并通过DiscountContext
类来管理这些策略。客户端可以在运行时根据需要切换不同的折扣策略。