1.策略模式官方定义及分析
- 策略模式也叫政策模式,允许程序在运行时选择一个算法执行,通常存在一类算法实现提供外部选择执行,这里的算法,也可以叫策略。
- 定义一类算法,各自独立封装实现,并且相互之间是可替换的。除此之外,由客户端决定具体使用何种算法。
两个定义中都提及到了算法一词,这里的算法含义比较宽泛,指的是一个业务操作。
定义中提到的 通常存在一类算法实现提供外部选择执行 ; 定义一类算法,各自独立封装实现,并且相互之间是可替换的。 很像是父类中定义方法,不同的子类去重写方法,所以说策略模式体现的是父类与子类的关系。但在很多时候,它是以接口的形式实现,将各个”子类“具有的公共方法抽象封装成接口方法,再用“子类”去实现接口,重写接口中的方法。如UML类图中所示。
图中包含OperationA和OperationB两个类,也可以称其为算法,算法内中A和B由各自的业务逻辑,do()方法,将这两个类的公共方法封装成一个策略类(接口)。然后引入一个Context类,这个类的作用是连接Strategy接口和客户端Client类,使策略类能被客户端给调用,Context被叫做上下文类。在Context类中传入Strategy接口的某一个实现类的实例,即A或B的实例对象,然后在类内部定义一个公共的executeStrategy()方法,客户端调用这个方法,即可获取到对应的A或B的实现方法。
综上,使用策略模式分为以下几个步骤:
1.定义抽象策略角色(Strategy): 即上图中的接口,接口中包括所有共用的方法。
2. 定义具体策略角色(ConcreteStrategy): 即上图中接口的实现类A和B。
3. 定义环境角色(Context): 即上图中的Context类,用于连接策略角色与客户端。
2.策略模式实现示例
使用策略模式实现计算器的加减乘除功能
定义抽象策略角色(Stratrgy)
public interface Operation {
/**
* 定义运算的共有方法
*/
int doOperation(int num1,int num2);
}
定义具体策略角色(ConcreteStrategy)
加法实现类
public class OperatonAdd implements Operation {
@Override
public int doOperation(int num1, int num2) {
return num1 + num2;
}
}
减法实现类
public class OperationSub implements Operation {
@Override
public int doOperation(int num1, int num2) {
return num1 - num2;
}
}
乘法实现类
public class OperationMultiply implements Operation {
@Override
public int doOperation(int num1, int num2) {
return num1 * num2;
}
}
除法实现类
public class OperationDivide implements Operation {
@Override
public int doOperation(int num1, int num2) {
return num1 / num2;
}
}
定义环境角色(Context)
并进行测试实现
public class Calculator {
private Operation operation;
public void setOperation(Operation operation) {
this.operation = operation;
}
public int doOperation(int num1,int num2){
return this.operation.doOperation(num1,num2);
}
//测试
public static void main(String[] args) {
Calculator calculator1 = new Calculator();
calculator1.setOperation(new OperatonAdd());
System.out.println(calculator1.doOperation(2, 1));
Calculator calculator2 = new Calculator();
calculator2.setOperation(new OperationSub());
System.out.println(calculator2.doOperation(2, 1));
Calculator calculator3 = new Calculator();
calculator3.setOperation(new OperationMultiply());
System.out.println(calculator3.doOperation(2, 2));
Calculator calculator4 = new Calculator();
calculator4.setOperation(new OperationDivide());
System.out.println(calculator4.doOperation(2, 2));
}
}
策略模式的使用场景
- 许多相关类仅仅是行为不同。
- 需要使用一个算法的不同实现。
- 算法使用了客户不应该知道的数据。策略模式可以避免暴露复杂的、与算法相关的数据结构。
- 一个类定义了很多行为,而且这些行为在这个类里的操作以多个条件语句的形式出现。策略模式将相关的条件分支移入它们各自的 Strategy 类中以代替这些条件语句。