在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改。
把行为和环境分割开来。环境类Context负责查询要做什么,各种算法则在具体策略类(ConcreteStrategy)中提供。
假设有一个计算的功能,分别有加减乘三种方法,如果需要通过传入的一个type去判断具体执行哪一个方法
,
如果使用传统的方法的话,我们就需要去使用多个if判断,现在只需要两三个,那么如果后面这种有几十种呢?
所以,在这里就需要去使用策略模式去解决,下面便对策略模式进行解决这个问题
演示类使用 Context 和策略对象来演示 Context 在它所配置或使用的策略改变时的行为变化
策略接口的定义,通常包含:处理策略业务逻辑的方法。
public interface Strategy {
public int doOperation(int num1, int num2);
}
创建实现接口的实体类,这样我们可以灵活的替换不同的实现方法
public class OperationAdd implements Strategy{
@Override
public int doOperation(int num1, int num2) {
return num1 + num2;
}
}
public class OperationSubtract implements Strategy{
@Override
public int doOperation(int num1, int num2) {
return num1 - num2;
}
}
public class executeStrategy implements Strategy{
@Override
public int doOperation(int num1, int num2) {
return num1 * num2;
}
}
策略模式包含一组同类的策略,在使用时我们通常通过类型来判断创建哪种策略来进行使用
上下文类,就是集成算法的类
该类的定义体现了多用组合,少用继承。针对接口,不针对实现两个设计原则。
public class Context {
private Strategy strategy;
public Context(Strategy strategy){
this.strategy = strategy;
}
public int executeStrategy(int num1, int num2){
return strategy.doOperation(num1, num2);
}
}
public class StrategyPatternDemo {
public static void main(String[] args) {
Context context = new Context(new OperationAdd());
System.out.println("10 + 5 = " + context.executeStrategy(10, 5));
context = new Context(new OperationSubtract());
System.out.println("10 - 5 = " + context.executeStrategy(10, 5));
context = new Context(new OperationMultiply());
System.out.println("10 * 5 = " + context.executeStrategy(10, 5));
}
}
输出结果:
10 + 5 = 15
10 - 5 = 5
10 * 5 = 50
在这里假设上面的三种实现类都是在com.app
里面
package com.app;
public class T1 {
public static void main(String[] args) {
try {
//创建类
String type = "concreteStrategyA ";
Class<?> class1 = Class.forName("com.app" + type);;
//创建实例化:相当于 new 了一个对象
Object object = class1.newInstance() ;
//向下转型
OperationAdd add = (OperationAdd) object ;
System.out.println("10 - 5 = " + add.doOperation(10, 5));
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
上面的代码有一点问题,那就是我们需要去new一个对象(反射的也是需要new已一个),如果在Spring项目中,通过new创建出来的对象中,无法使用@Resource或@Autowired 注解实例化service层注入。
因为Spring的注入是在项目启动的时候执行的,所以后期new出来的实例对象中的注入注解就不会生效了
。
public interface Strategy {
public int doOperation(int num1, int num2);
}
创建实现接口的实体类,这样我们可以灵活的替换不同的实现方法
@Component("add")
public class OperationAdd implements Strategy{
@Override
public int doOperation(int num1, int num2) {
return num1 + num2;
}
}
@Component("substract")
public class OperationSubtract implements Strategy{
@Override
public int doOperation(int num1, int num2) {
return num1 - num2;
}
}
@Component("multiply")
public class executeStrategy implements Strategy{
@Override
public int doOperation(int num1, int num2) {
return num1 * num2;
}
}
策略模式包含一组同类的策略,在使用时我们通常通过类型来判断创建哪种策略来进行使用
上下文类,就是集成算法的类
该类的定义体现了多用组合,少用继承。针对接口,不针对实现两个设计原则。
@Component
public class Context {
@Autowired
private Map<String, Strategy> strategyMap;
public Strategy build(String type){
return strategyMap.get(type);
}
}
@Component
public class StrategyPatternDemo {
@Autowired
private Context context;
public void test(){
Strategy strategy = context.build("add");
int add = startegy.doOperation(10, 5);
System.out.println("10 + 5 = " + add);
Strategy strategy = context.build("subtract");
int subtract = startegy.doOperation(10, 5);
System.out.println("10 - 5 = " + subtract);
Strategy strategy = context.build("multiply");
int multiply = startegy.doOperation(10, 5);
System.out.println("10 * 5 = " + multiply);
}
}
输出结果:
10 + 5 = 15
10 - 5 = 5
10 * 5 = 50