1 策略模式概述
策略模式是用来封装变化的。
同一个功能可由多个算法进行实现(或代码,不同的业务使用不同的处理方式)。
当不同的行为都放在一个类中的时候,就需要使用条件语句if-else-switch来进行选择。
但是策略模式是可以将这些不同的行为封装在独立的Strategy类中,再编写一个Context类来选择对Strategy对象的引用。
这样就可以根据客户端的选择,在不同时间应用不同的业务。
2 策略模式结构
组成:
- 抽象策略类(Strategy):定义所有支持的算法的公共接口。 Context使用这个接口来调用某ConcreteStrategy定义的算法。
- 具体策略类(ConcreteStrategy):以Strategy接口实现某具体算法。
- 环境类Context:用一个ConcreteStrategy对象来配置。维护一个对Strategy对象的引用。可定义一个接口来让Strategy访问它的数据。
3 代码实现:
为了便于理解思想,下面的代码实现较为简单。
1)定义一个抽象Strategy类,声明一个算法:
public abstract class Travel {
public abstract void travelWay();
}
2)具体的策略类:
TravelWithAir :
public class TravelWithAir extends Travel {
@Override
public void travelWay() {
System.out.println("用坐飞机的方式去旅行。。。");
}
}
TravelWithRun :
public class TravelWithRun extends Travel{
@Override
public void travelWay() {
System.out.println("用跑步的方式去旅行。。。");
}
}
TravelWithTrain :
public class TravelWithTrain extends Travel{
@Override
public void travelWay() {
System.out.println("用坐火车的方式去旅行。。。");
}
}
3)环境类Context:根据用户的选择选择不同的实现算法。
public class TravelContext {
Travel travel = null;
public TravelContext(String type){
switch(type){
case "run" :
travel = new TravelWithRun();
break;
case "air" :
travel = new TravelWithAir();
break;
case "train" :
travel = new TravelWithTrain();
break;
}
}
public void getTravelWays(){
travel.travelWay();
}
}
4)测试:
public class Main {
public static void main(String[] args) {
//模拟用户选择
String select = "run";
TravelContext context = new TravelContext(select);
context.getTravelWays();
select = "air";
context = new TravelContext(select);
context.getTravelWays();
select = "train";
context = new TravelContext(select);
context.getTravelWays();
}
}
4 Spring中策略模式的实现
在Spring中有多个地方使用到策略模式,如Aop中代理对象的创建就使用到了策略模式。
如上图:
AopProxy接口就代表抽象策略类;
Cglib2AopProxy 和 JdkDynamicAopProxy 代表两种策略的实现方式;
ProxyFactoryBean 代表 Context,根据所要代理的类是类还是接口来选择是使用JDK代理方式 还是 CGLIB方式。
参考:《深入分析Java Web技术内幕》