写代码的时候经常遇到下面的情况,之前处理过一次,使用了策略模式,当时不是很理解,于是自己写了个简单的例子,清晰了逐渐。
首先看下面的代码,
public class Proxy {
private static String LOC_TOP = "top";
private static String LOC_LEFT = "lrft";
private static String LOC_RIGHT = "fight";
private static String LOC_BOT = "bot";
private static String LOC_CENTER = "center";
public static String getLocation(String loc){
if(LOC_TOP.equals(loc)){
return LOC_TOP;
}else if(LOC_LEFT.equals(loc)){
return LOC_LEFT;
}else if(LOC_RIGHT.equals(loc)){
return LOC_RIGHT;
}else if(LOC_BOT.equals(loc)){
return LOC_BOT;
}else{
return LOC_CENTER;
}
}
public static void main(String[] args) {
System.out.println(getLocation(LOC_BOT));
}
}
上述代码如果需要添加一个位置信息,需要做
(1)增加一个常量
(2)加一个else if
(3)增加一个常量对应的实现
如何改进?
使用策略模式,只需要增加一个此策略对应的实现即可,原有的逻辑不需要变更,扩展方便
何为策略模式?
定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。
何时使用策略模式?
1) 如果在一个系统里面有许多类,它们之间的区别仅在于它们的行为,那么使用策略模式可以动态的让一个对象在许多行为中选择一种行为。
2) 如果系统需要动态地在几种算法中选择一种。那么这些算法可以包装到一个个的具体算法类里面,而这些算法类都是一个抽象算法类的子类。换言之,这些具体算法类均有统一的接口,由于多态性原则。客户端可以选择使用任何一个具体算法类,并只持有一个数据类型是抽象算法类的对象。
3) 一个系统的算法使用的数据不可以让客户端知道。策略模式可以避免让客户端涉及到不必要接触到的复发的和只与算法有关的数据。
策略接口,用来约束一系列具体的策略算法。Context使用这个接口来调用具体的策略实现定义的算法。
ConcreteStrategy:
具体的策略实现,也就是具体的算法实现。
Context:
上下文,负责和具体的策略类交互,通常上下文会持有一个真正的策略实现,上下文还可以让具体的策略类来获取上下文的数据,甚至让具体的策略类来回调上下文的方法。
/**
*相当于上图中的context,方法的参数里面是一个接口
*调用者可以根据策略的不同,传入不同的实现类,从而实现扩展,
*同时,原始代码里面的逻辑不用变化
*/
public class ProxyStra {
public static String getLocation(Strategy strategy){
return strategy.getResult();
}
//相当于客户端的调用
public static void main(String[] args) {
System.out.println(ProxyStra.getLocation(new TopStrategy()));
}
}
public interface Strategy {
public String getResult();
}
public class TopStrategy implements Strategy {
@Override
public String getResult() {
return "top";
}
}
定义一系列算法;
避免多重条件语句;
更好的扩展性;
-----------------------------------------------
客户必须了解每种策略的不同;
增加了对象数目;
只适合扁平的算法结构;