策略模式定义
定义一系列的算法,把每一个算法封装起来, 并且使它们可相互替换。策略模式模式使得算法可独立于使用它的客户而独立变化。
- Context:用来操作策略的上下文环境。
- Stragety:策略的抽象。
- ConcreteStragetyA、ConcreteStragetyB:具体的策略实现。
策略模式具体实现
抽象策略:
通常情况下为一个接口,当各个实现类中存在着重复的逻辑时,则使用抽象类来封装这部分公共的代码,此时,策略模式看上去更像是模版方法模式。
public interface Stragety {
void doSomething();
}
具体策略:
具体策略角色通常由一组封装了算法的类来担任,这些类之间可以根据需要自由替换。
public class ConcreteStragetyA implements Stragety{
@Override
public void doSomething() {
System.out.println("A对象执行A方法");
}
}
public class ConcreteStragetyB implements Stragety{
@Override
public void doSomething() {
System.out.println("B对象执行B方法");
}
}
封装类:
也叫上下文,对策略进行二次封装,目的是避免高层模块对策略的直接调用。
public class Context {
private Stragety mStragety;
public Context(Stragety mStragety ){
this.mStragety = mStragety;
}
public void execute(){
mStragety.doSomething();
}
}
测试
public class Demo {
public static void main(String[] args) {
Context context;
//A对象执行方法
context = new Context(new ConcreteStragetyA());
context.execute();
//B对象执行方法
context = new Context(new ConcreteStragetyB());
context.execute();
}
}
结果
A对象执行A方法
B对象执行B方法
策略模式优缺点
优点
策略模式提供了管理相关的算法族的办法。策略类的等级结构定义了一个算法或行为族。恰当使用继承可以把公共的代码转移到父类里面,从而避免重复的代码。
使用策略模式可以避免使用多重条件转移语句。多重转移语句不易维护,它把采取哪一种算法或采取哪一种行为的逻辑与算法或行为的逻辑混合在一起,统统列在一个多重转移语句里面,比使用继承的办法还要原始和落后。
缺点
客户端必须知道所有的策略类,并自行决定使用哪一个策略类。这就意味着客户端必须理解这些算法的区别,以便适时选择恰当的算法类。换言之,策略模式只适用于客户端知道所有的算法或行为的情况。
策略模式造成很多的策略类,每个具体策略类都会产生一个新类。有时候可以通过把依赖于环境的状态保存到客户端里面,而将策略类设计成可共享的,这样策略类实例可以被不同客户端使用。换言之,可以使用享元模式来减少对象的数量。
策略模式使用场景
对客户隐藏具体策略(算法)的实现细节,彼此完全独立。
针对同一类型问题的多种处理方式,仅仅是具体行为有差别时。
一个类定义了很多行为,而且这些行为在这个类里的操作以多个条件语句的形式出现。策略模式将相关的条件分支移入它们各自的 Strategy 类中以代替这些条件语句。