策略模式(Strategy Pattern)又叫作政策模式(Policy Pattern),它将定义的算法家族分别封装起来,让它们之间可以互相替换,从而让算法的变化不会影响到使用算法的用户,属于行为型设计模式。
原理:面向对象的继承与多态
场景:
由客户端选择策略算法,解决if else或switch case带来的臃肿性问题
(1)针对同一类型问题,有多种处理方式,每一种都能独立解决问题。
(2)需要自由切换算法的场景。
(3)需要屏蔽算法规则的场景。
Context上下文角色,用于操作策略的上下文环境,屏蔽高层模块对策略、算法的直接访问,隔离客户端于策略类的耦合
public interface IStrategy {void doStrategy();}public class ConcreteStrategyA implements IStrategy{@Overridepublic void doStrategy() {}}public class ConcreteStrategyB implements IStrategy{@Overridepublic void doStrategy() {}}public class Context {private IStrategy strategy;public Context(IStrategy strategy) {this.strategy = strategy;}public void doStrategy(){this.strategy.doStrategy();}}public class Client {public static void main(String[] args){Context context = new Context(new ConcreteStrategyA());context.doStrategy();context = new Context(new ConcreteStrategyB());context.doStrategy();}}
优点
- 策略可以由客户端自由指定
- 避免复杂if else,符合开闭原则
缺点
- 类膨胀
- 所有策略类都需要对外暴露(可以配合工厂模式、享元模式等修正)
如果策略类超过4个,就需要考虑使用混合模式解决类膨胀和对外暴露的问题,用工厂模式来实现策略类的声明
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class StrategyFactory {
private static Map<String,IStrategy> strategyMap = new ConcurrentHashMap<>();
static {
strategyMap.put(StrategyEnum.A.getCode(),StrategyEnum.A.getStrategy());
strategyMap.put(StrategyEnum.B.getCode(),StrategyEnum.B.getStrategy());
}
private static IStrategy empty = new DefaultConcreteStrategy();
public IStrategy getStrategy(String code){
IStrategy iStrategy = strategyMap.get(code);
return iStrategy == null ? empty : iStrategy;
}
}
public enum StrategyEnum {
A("A",new ConcreteStrategyA()),
B("B",new ConcreteStrategyB())
;
StrategyEnum(String code, IStrategy strategy) {
this.code = code;
this.strategy = strategy;
}
private String code;
private IStrategy strategy;
public String getCode() {
return code;
}
public IStrategy getStrategy() {
return strategy;
}
}
public class Client {
public static void main(String[] args){
String code = "A";
StrategyFactory strategyFactory = new StrategyFactory();
IStrategy strategy = strategyFactory.getStrategy(code);
strategy.doStrategy();
}
}
框架
- Comparator
- Spring中Resource类
- Spring初始化不同类型的类采用不同的初始化策略,InstantiationStrategy->SimpleInstantiationStrategy/CglibSubclassingInstantiationStrategy
