策略模式
一个策略接口,各个策略实现类,一个封装类Context,一个场景类,一个原生的策略模式就需要这么多.
但是这里的封装类Context类意义大吗? 高层模块还是会接触到具体的策略类 所以书上说,这种单独的策略模式用的很少.可以和工厂方法搭配使用
书上介绍了一种枚举类使用策略模式的方法挺好
public enum Caculator {
ADD("+") {
public int exec ( int a, int b){
return (a + b);
}
},
SUB("-"){
public int exec ( int a, int b){
return (a - b);
}
};
private String value;
private Caculator(String _value){
this.value = _value;
}
public abstract int exec(int a, int b);
}
这个类十分清晰
工厂模式搭配使用
工厂接口:
public interface Factory {
public Strategy createStrategy(StrategyEnum strategyEnum);
}
public class StrategyFactory implements Factory {
@Override
public Strategy createStrategy(StrategyEnum strategyEnum) {
Strategy strategy = null;
String clazzName = strategyEnum.getStrategyName();
try {
Class<?> clazz = Class.forName(clazzName);
strategy = (Strategy) clazz.newInstance();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return strategy;
}
}
此时,我们可以在场景类
Factory factory = new StrategyFactory();
Strategy strategy = factory.createStrategy(StrategyEnum.ADD);
int result = strategy.exec(3 , 5);
System.out.println(result);
即可实现我们的功能,但是这里又有一个问题了,每次执行,需要分为四步,得到工厂,获取策略,封装策略,执行方法.顺序不能混乱.我们必须得记住这四步.下面就可以用到门面模式
门面模式
门面模式用于屏蔽子系统内的复杂性,给外界一个固定的访问途径 有几个注意点:
- 门面类里不能涉及到具体的业务逻辑, 因为一旦你的门面类里有具体的业务了,那会形成一个倒以来,子系统没有了门面类就不能访问
- 门面类是外面和子系统访问的接口,所以设计时一定要仔细,他是不能轻易被改变的
- 门面类可以不止一个,可以按照功能划分,权限划分等等
现在,我们希望用了这个门面模式达到一种效果,在场景类里,
CalculatorFacade facade = new CalculatorFacade();
int result1 = facade.exec(5, 6, StrategyEnum.SUB);
System.out.print(result1);
这样我们高层模块就不需要接触具体的策略类
public class CalculatorFacade {
private FacadeContext context = new FacadeContext();
CalculatorFacade(){}
public int exec(int a, int b, StrategyEnum strategyEnum){
return this.context.calculate(a, b, strategyEnum);
}
}
上面的CalculatorFacde 就是具体的门面类, 可以让高层不再依赖具体的子系统,看里面也没有涉及到业务逻辑,而是交给FacadeContext 处理.
public class FacadeContext {
private Factory factory = new StrategyFactory();
private StrategyContext context = new StrategyContext(null);
public FacadeContext(){
}
public int calculate(int a, int b, StrategyEnum strategy){
this.context.setStrategy(this.factory.createStrategy(strategy));
return this.context.exec(a, b);
}
}
在这里面,通过工厂生产具体的策略类,交给策略类的封装类.让他去执行