定义
策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式
从定义中来看,策略模式的目标是优化类的行为选择,将选择行为和行为本身实现细节拆分,达到选择行为只控制流程,比如你要从A地到达B地,现在你有三种交通方式,汽车,自行车,火车。三种方式的耗时,路线选择都不一样。如果采取策略模式来描述这个场景,则选择何种交通方式就是在控制流程,而具体的流程细节是由单独的行为本身实现。
实例
public interface IntOpt {
public int doOpt(int num, int num2);
}
public class Add implements IntOpt {
@Override
public int doOpt(int num, int num2) {
return num + num2;
}
}
public class Multiply implements IntOpt {
@Override
public int doOpt(int num, int num2) {
return num * num2;
}
}
public class IntOptContext {
private IntOpt mIntOpt;
public IntOptContext(IntOpt intOpt){
this.mIntOpt = intOpt;
}
public int doOpt(int num, int nums){
if (mIntOpt != null) {
return mIntOpt.doOpt(num, nums);
}
return 0;
}
}
上述接口描述了四则运算中的加法和乘法,IntOptContext属于策略的包装类,加上该类可以给当前框架充当中间层,以至于有改动的时候不用去修改客户端代码和策略实现,如果不用该包装,直接使用选择的策略类来操作也是可以的。如果是单个算法实现,也可以采用策略枚举
public enum IntOptEnum {
ADD("+"){
@Override
public int doOpt(int num, int nums) {
return num + nums;
}
},
SUB("-"){
@Override
public int doOpt(int num, int nums) {
return num - nums;
}
};
String symbol;
private IntOptEnum(String symbol){
this.symbol = symbol;
}
public String getSymbol(){
return symbol;
}
public abstract int doOpt(int num, int nums);
}
总结
优点: 1、算法可以自由切换。 2、避免使用多重条件判断。 3、扩展性良好。
缺点: 1、策略类会增多。 2、所有策略类都需要对外暴露。
使用场景: 1、如果在一个系统里面有许多类,它们之间的区别仅在于它们的行为,那么使用策略模式可以动态地让一个对象在许多行为中选择一种行为。 2、一个系统需要动态地在几种算法中选择一种。 3、如果一个对象有很多的行为,如果不用恰当的模式,这些行为就只好使用多重的条件选择语句来实现。
注意事项:如果一个系统的策略多于四个,就需要考虑使用混合模式,解决策略类膨胀的问题。