策略模式作为一种软件设计模式,指对象有某个行为,但是在不同的场景中,该行为有不同的实现算法。比如每个人都要“交个人所得税”,但是“在美国交个人所得税”和“在中国交个人所得税”就有不同的算税方法。----WIKIPEDIA
个人理解
策略模式从名字就可以看出,有多种选择,不同的策略对应着不同的实现方式,那么一般的形式为一个接口采用多种实现方式(也就是提供了不同的策略),然后再提供一个策略的选择类即可,定义中:定义一组算法,将每个算法都封装起来,并且使得他们之间可以相互的转换。通过上面我提到的这种方式来看,一组算法就是指的多种的实现方式,而将每个算法都封装起来并使得他们之间可以互换,实现了统一的接口,自然可以实现互换了。
案例解析
举个比较常见的例子,红绿灯,当你过马路的时候,会看一下红绿灯,从小就学会了:绿灯行、红灯停、黄灯亮了等一等。这样的话,相当于三个策略,根据这个实例来设计类的结构。
其中,TrafficLight接口提供了统一的接口,其他的几个类实现该接口并实现其中的方法,那么这样的设计就可以保证其可以进行替换,然后Context类则提供了策略的选择类,与其说是选择不如说是提供了外界访问的入口,只需要根据不同的策略创建好context的实例然后直接调用其方法就可以了,这里的名称并不一定要和接口中相同。
接口代码:
public interface TrafficLight {
/**
* 输出该灯对应的注意事项
*/
public void checkLight();
}
策略的选取类
public class Context {
private TrafficLight light;
public Context() {
super();
}
public Context(TrafficLight light) {
super();
this.light = light;
}
public void checkLight(){
this.light.checkLight();
}
}
接口的实现
(只列出一个)
public class RedLight implements TrafficLight {
@Override
public void checkLight() {
System.out.println("停");
}
}
测试类
public static void main(String[] args) {
Context context = null;
context = new Context(new RedLight());
context.checkLight();
context = new Context(new YellowLight());
context.checkLight();
context = new Context(new GreenLight());
context.checkLight();
}
策略模式拓展
一般策略模式
加减运算,按照上面的架构方式,完全可以实现,基本的形式为,同样提供一个接口和Context供选择策略的类即可。这里只列出其类图,代码可以根据下面的链接进行下载设计模式源代码下载。
策略枚举
通过枚举实现策略模式的一个示例,主要的代码如下
public enum Calculator {
ADD("+"){
@Override
public int cal(int a, int b) {
return a + b;
}
},
SUB("-"){
@Override
public int cal(int a, int b) {
return a - b;
}
};
String value = "";
private Calculator(String value) {
this.value = value;
}
public abstract int cal(int a, int b);
}
public class Context {
public void cal(int a,String operator, int b){
if("+".equals(operator)){
System.out.println(Calculator.ADD.cal(a, b));
}else if("-".equals(operator)){
System.out.println(Calculator.SUB.cal(a, b));
}
}
}
测试类
public static void main(String[] args) {
Context context = new Context();
context.cal(1, "+", 2);
context.cal(1, "-", 2);
}
1. 他本身是枚举。
2. 他可以实现策略模式。
策略模式的优点
1. 具体实现可以自由的切换。
2. 避免了多重的判断。
3. 扩展性比较好,如果再多的策略的时候,可以继续实现统一的接口,实现其方法即可。
策略模式的缺点
1. 策略类的数量增多。
2. 所有的策略类都需要对外暴露,上层模块必须知道有哪些策略然后才能知道应该使用哪个策略,这与迪米特法则相违背,不过可以通过其他的模式来弥补其缺陷,比如:工厂方法模式、代理模式、享元模式。
策略模式适用场景
1. 多个类只在具体的实现上有所不同。
2. 具体的实现方法可以进行自由的切换。
设计模式源代码下载
设计模式系列文章推荐阅读
"围观"设计模式(18)--行为型之模板方法模式(TemplateMethod Pattern)