策略模式,一个类的行为或算法可以再运行时更改,属于行为型模式。
定义一系列算法,封装每一个算法并使他们可以互换,策略模式可以让算法独立于使用它的客户端。
Class Diagram- Strategy接口定义算法族,每个算法子类实现
beHavior()
方法。当各实现类存在重复逻辑可以在接口中进行默认实现,此时策略模式更像是模板方法模式。 - ConcreteStrategy是具体算法实现类,同级之间需要可以自有替换。
- Context是调用算法族的类,其中的
doSomething()
会调用beHavior()
方法,而setStrategy(Strategy)
用来改变算法实现类,也就是说可以动态的改变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 OperationSubstract implements Strategy{
@Override
public int doOperation(int num1, int num2) {
return num1 - num2;
}
}
- 通过Context类调用Strategy
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);
}
}
- 使用Context类,查看改变策略Strategy时的行为变化
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 OperationSubstract());
System.out.println("10 - 5 = " + context.executeStrategy(10, 5));
}
}
输出结果:
10 + 5 = 15
10 - 5 = 5
优缺点
优点:
- 策略类之间自由切换
- 易于拓展。只需要增加一个新的Strategy实现类,基本可以不修改原有代码
- 避免使用多重条件。如果不使用策略模式,选择算法的方式需要通过条件判断,而使用多重条件判断时十分不利于维护的
缺点:
- 维护各策略类会带来额外的开销,如果策略过多则不合适
- 必须对客户端暴露所有的策略类,由于策略的选择在客户端进行,因此客户端必须知道所有策略和之间的区别,才能进行正确的选择,这违背了迪米特法则(一个类应该对其他对象保持最小的理解)
网友评论