策略模式
1.定义:
策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户端而独立变化。
2.使用场景:
- 针对同一类型问题的多种处理方式,仅仅是具体行为有差别时;
- 需要安全的封装多种同一类型的操作时;
- 出现同一抽象类有多个子类,而又需要使用else-if或者switch-case来具体选择子类时。
3.UML图
4.详解:
策略模式将一系列的算法或策略抽象出一个统一的接口,不同的算法或策略有不同的实现类,这样在客户端就可以通过注入不同的实现对象来实现不同算法或策略的动态替换,它可扩展性、可维护性更高。它是一种行为型设计模式。
策略模式主要用来分离算法,在相同的行为抽象下有不同的具体实现策略,这也很好的演示了OCP原则。
- 优点:结构清晰明了、使用简单直观;降低耦合,扩展方便;操作封装更彻底,数据更安全;
- 缺点:随着策略的增加,子类会越来越多。
下面就以数学中的加减乘除举例,使用两种方案实现,详见下面代码。
原始方案:
public static class Calculator {
private static final String ADD = "+";
private static final String SUBTRACT = "-";
private static final String MULTIPLY = "*";
private static final String DIVIDE = "/";
public static float calculate(float a, float b, String type) {
switch (type) {
case ADD:
return a + b;
case SUBTRACT:
return a - b;
case MULTIPLY:
return a * b;
case DIVIDE:
return a / b;
default:
return 0;
}
}
}
测试代码:
public static void main(String[] args) {
//原始方案
System.out.println(Calculator.calculate(7, 5, Calculator.ADD));
System.out.println(Calculator.calculate(7, 5, Calculator.SUBTRACT));
System.out.println(Calculator.calculate(7, 5, Calculator.MULTIPLY));
System.out.println(Calculator.calculate(7, 5, Calculator.DIVIDE));
}
上面这种方案是很多程序猿会选择的方案,因为相对简单。但是如果随着需求的增加,要取余/多次幂等操作,就要修改Calculator 类,并在其中加入case条件,这样就违背了OCP原则。
策略模式修改后的方案
首先,上面的加减乘除四种方法,可以抽象出一个统一接口,如下:
public interface CalculateMethod {
float calculate(float a, float b);
}
接着就是具体的实现类:加减乘除
public static class Add implements CalculateMethod {
@Override
public float calculate(float a, float b) {
return a + b;
}
}
public static class Subtract implements CalculateMethod {
@Override
public float calculate(float a, float b) {
return a - b;
}
}
public static class Multiply implements CalculateMethod {
@Override
public float calculate(float a, float b) {
return a * b;
}
}
public static class Divide implements CalculateMethod {
@Override
public float calculate(float a, float b) {
return a / b;
}
}
然后就是最关键的策略模式修改后类了
public static class StrategyCalculator {
private CalculateMethod method;
public StrategyCalculator setStrategy(CalculateMethod method) {
this.method = method;
return this;
}
public float calculate(float a, float b) {
return method.calculate(a, b);
}
}
上面的代码清晰明了,就是通过设置具体的策略,然后让策略去执行相应的操作。是不是很简单?然后就是扩展性很强,如上所述,假如需要取余,仅添加一个类Mod实现CalculateMethod 接口即可,而不需修改已有的类。详见代码:
public static class Mod implements CalculateMethod {
@Override
public float calculate(float a, float b) {
return a % b;
}
}
测试代码:
public static void main(String[] args) {
//策略模式修改方案
StrategyCalculator strategyCalculator = new StrategyCalculator();
System.out.println(strategyCalculator.setStrategy(new Add()).calculate(7, 5));//12.0
System.out.println(strategyCalculator.setStrategy(new Subtract()).calculate(7, 5));//2.0
System.out.println(strategyCalculator.setStrategy(new Multiply()).calculate(7, 5));//35.0
System.out.println(strategyCalculator.setStrategy(new Divide()).calculate(7, 5));//1.4
System.out.println(strategyCalculator.setStrategy(new Mod()).calculate(7, 5));//2.0
}
网友评论