策略模式要解决的问题:
一个问题根据不同的情况有多种选择的时候,我们一般的做法是写一个管理类为不同的解决方案设置不同的标识,当需要解决某种情况的问题的时候就根据标识配合 if else 语句来进行区分,同时各种解决方案的具体方法也会写到这个类中,这样导致的后果就是后期如果想添加新的方案就要修改源码,违反了软件设计的开闭原则,增加了风险不利于后期扩展。
现在引入我们的策略模式让代码更清晰,更加易于维护。
先上uml 图
先上平常普通的使用方法:
public class Context {
public static class Const{
public final static int CAR = 101;
public final static int BUS = 102;
public final static int TAXI = 103;
}
/**
* 根据距离计算车费
* @return
*/
public int calFare(int flag,int distance){
if(flag == Const.BUS){
return 2;
}else if(flag == Const.CAR){
return calCarFare(distance);
}else if(flag == Const.TAXI){
return calTaxiFare(distance);
}
return 0;
}
/**
* 计算出租车费用
* @param distance
* @return
*/
private int calTaxiFare(int distance) {
//...根据里程计算出租车费用...
return 0;
}
/**
* 计算黑车费用
*/
private int calCarFare(int distance) {
//...根据里程计算黑车费用...
return 0;
}
}
具体调用:
public static void main(String[] args){
Context context = new Context();
int fare = context.calFare(Context.Const.BUS, 20);
System.out.println(fare);
}
如果我们还想添加其他的交通工具就要修改Context.java的源码,新增flag。接下来我们使用策略模式改造一下。
public interface IStragety {
/**
* 根据里程计算车费
* @param distance
* @return
*/
public abstract int calFare(int distance);
}
黑车策略
public class CarStragety implements IStragety {
@Override
public int calFare(int distance) {
return 0;
}
}
公交车策略
public class BusStragety implements IStragety {
@Override
public int calFare(int distance) {
return 0;
}
}
出租车策略
public class TatxiStragety implements IStragety {
@Override
public int calFare(int distance) {
return 0;
}
}
给客户提供的调用类
public class Context {
private IStragety mStragety;
public void setStragety(IStragety stragety){
this.mStragety = stragety;
}
public int calFare(int distance){
return mStragety.calFare(distance);
}
}
实际使用:
public static void main(String[] args){
Context context = new Context();
context.setStragety(new BusStragety());
int fare = context.calFare(200);
System.out.println(fare);
}
如果我们想增加其他出行交通策略,只需要新增加一个相应的类就可以了,不用破坏原有的代码,这样看是不是很方便。