- 策略模式属于对象行为模式,它通过对算法进行封装,把使用算法的责任和实际算法分割开来。
- 抽象策略(Strategy)类:定义了一个公共接口,一般使用接口或抽象类实现。
- 具体策略(Concrete Strategy)类:实现了抽象策略定义的接口,提供具体的算法实现。
- 环境(Context)类:持有一个策略类的引用,最终给客户端调用。
- 策略模式实现就是将一组算法封装到一个策略类里,根据些算法特性(如beanName)来获取对应算法来调用
- 下面的栗子把对象都交给Spring去管理
/**
* 抽象策略类
*/
@Component
public interface Strategy {
// 策略方法
void strategyMethod();
}
/**
* 策略类A
*/
@Component
public class ConcreteStrategyA implements Strategy {
@Override
public void strategyMethod() {
System.out.println("具体策略A的策略方法被访问");
}
}
/**
* 策略类B
*/
@Component
public class ConcreteStrategyB implements Strategy {
@Override
public void strategyMethod() {
System.out.println("具体策略B的策略方法被访问!");
}
}
@Component
public class StrategyFactory {
@Autowired
private final Map<String, Strategy> strategyMap = new HashMap<>();
public Strategy getStrategy(String strategyName) {
Strategy strategy = strategyMap.get(strategyName);
return strategy;
}
public static void main(String[] args) {
AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
StrategyFactory strategyFactory = annotationConfigApplicationContext.getBean(StrategyFactory.class);
Strategy strategy = strategyFactory.getStrategy("concreteStrategyB");
strategy.strategyMethod();
}
}
@Configuration
@ComponentScan(value = "com.zwh.strategy")
public class AppConfig {
}
- 这里通过main方法来调用环境类,实际应用可以实注入来调用
- 自动注入的时候可以将Strategy注入到Map里,key为beanName
- 默认通过beanName来获取对应策略算法,然后执行策略方法(spring默认beanName为类名首字母小写,你也可以指定特定name)
上述main方法执行输出:具体策略B的策略方法被访问!
【题外】:
- 策略模式一定程度上可以提代if… esle… 多重条件处理,如上述普通的条件分支实现如下,显然条件多了就不太优雅~
if ("concreteStrategyA".equals(beanName)) {
new ConcreteStrategyA().strategyMethod();
} else if ("concreteStrategyB".equals(beanName)) {
new ConcreteStrategyB().strategyMethod();
} else {
}
【参考】:
策略模式在Spring中的应用