它定义了一系列算法,将每个算法都封装起来,并使它们之间可以互换。
策略模式由三个角色组成:
- Context(上下文):上下文是使用某个算法的类,它委托算法对象完成具体的操作。上下文需要通过接口或抽象类与算法进行交互。
- Strategy(抽象策略):抽象策略定义了所有具体策略所需实现的方法,是具体策略的公共接口。
- ConcreteStrategy(具体策略):具体策略是实现抽象策略的具体算法实现,具体策略类需要实现抽象策略定义的所有方法。
public enum StrategyType {
STRATEGY_A,
STRATEGY_B,
STRATEGY_C
}
public interface Strategy {
void doSomething();
}
@Service("strategyA")
public class StrategyA implements Strategy {
@Override
public void doSomething() {
System.out.println("执行策略A");
}
}
@Service("strategyB")
public class StrategyB implements Strategy {
@Override
public void doSomething() {
System.out.println("执行策略B");
}
}
@Service("strategyC")
public class StrategyC implements Strategy {
@Override
public void doSomething() {
System.out.println("执行策略C");
}
}
@Component
public class StrategyFactory {
@Autowired
private ApplicationContext context;
private final Map<StrategyType, String> strategyMap = new EnumMap<>(StrategyType.class);
public StrategyFactory() {
strategyMap.put(StrategyType.STRATEGY_A, "strategyA");
strategyMap.put(StrategyType.STRATEGY_B, "strategyB");
strategyMap.put(StrategyType.STRATEGY_C, "strategyC");
}
public Strategy getStrategy(StrategyType type) {
String beanName = strategyMap.get(type);
if (beanName == null) {
throw new IllegalArgumentException("Unsupported strategy type: " + type);
}
return context.getBean(beanName, Strategy.class);
}
}
@Service
public class ClientService {
@Autowired
private StrategyFactory strategyFactory;
public void doSomething(StrategyType type) {
Strategy strategy = strategyFactory.getStrategy(type);
strategy.doSomething();
}
}
一个经典的 Java 策略模式案例是实现一个商场促销系统。商场销售人员根据不同的促销策略,对商品进行不同的促销折扣,如满100减20元、固定折扣8折、第二件半价等等。这里的促销策略可以看作是不同的算法,使用策略模式可以方便地实现不同的算法。
在实现时,我们可以定义一个接口 `DiscountStrategy`,其中包含一个折扣计算的方法 `calculateDiscount`,然后具体的促销策略都实现这个接口,实现自己的折扣计算方法。具体代码示例如下:
// 折扣策略接口
public interface DiscountStrategy {
double calculateDiscount(double price);
}
// 满100减20元策略
public class OverDiscountStrategy implements DiscountStrategy {
@Override
public double calculateDiscount(double price) {
if (price >= 100) {
return price - 20;
}
return price;
}
}
// 固定折扣8折策略
public class FixDiscountStrategy implements DiscountStrategy {
@Override
public double calculateDiscount(double price) {
return price * 0.8;
}
}
// 第二件半价策略
public class HalfDiscountStrategy implements DiscountStrategy {
@Override
public double calculateDiscount(double price) {
return price * 1.5;
}
}
public class ShoppingCart {
private DiscountStrategy discountStrategy;
private List<Double> items = new ArrayList<>();
public ShoppingCart(DiscountStrategy discountStrategy) {
this.discountStrategy = discountStrategy;
}
public void addItem(double price) {
items.add(price);
}
public double calculateTotalPrice() {
double totalPrice = 0;
for (Double item : items) {
totalPrice += discountStrategy.calculateDiscount(item);
}
return totalPrice;
}
}
public class Main {
public static void main(String[] args) {
DiscountStrategy overDiscountStrategy = new OverDiscountStrategy();
DiscountStrategy fixDiscountStrategy = new FixDiscountStrategy();
DiscountStrategy halfDiscountStrategy = new HalfDiscountStrategy();
ShoppingCart shoppingCart = new ShoppingCart(overDiscountStrategy);
shoppingCart.addItem(80);
shoppingCart.addItem(120);
System.out.println(shoppingCart.calculateTotalPrice());
shoppingCart = new ShoppingCart(fixDiscountStrategy);
shoppingCart.addItem(80);
shoppingCart.addItem(120);
System.out.println(shoppingCart.calculateTotalPrice());
shoppingCart = new ShoppingCart(halfDiscountStrategy);
shoppingCart.addItem(80);
shoppingCart.addItem(120);
System.out.println(shoppingCart.calculateTotalPrice());
}
}