TA的每日心情 | 开心 2021-3-12 23:18 |
---|
签到天数: 2 天 [LV.1]初来乍到
|
策略模式(Strategy):定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。策略模式使得算法可独立于使用它的客户而变化。
适用场景:
1、许多相关的类仅仅是行为有异。“策略”提供了一种用多个行为中的一个行为来配置一个类的方法;
2、需要使用一个算法的不同变体;
3、算法使用客户不应该知道的数据。可使用策略模式以避免暴露复杂的、与算法相关的数据结构;
4、一个类定义了多种行为, 并且这些行为在这个类的操作中以多个条件语句的形式出现。将相关的条件分支移入它们各自的Strategy 类中以代替这些条件语句。
通用类图:(略)
实际上,策略模式是采用了面向对象的继承和多态机制,客户根据自己的业务需要调用上下文(Context 类)获得相应的具体策略、算法实现。
假设我们要实现一个非常简单的计算机,只能进行加减操作。一般我们会这样设计:根据传入的 String 型参数使用 if… else… 语句判断用户需要哪种操作。
代码如下:
- [/code]
-
- class Calculator {
- private final static String ADD = "+";
- private final static String SUB = "-";
-
- public int operation (int a, int b, String operator) {
- int result = 0;
- if(this.ADD.equals(operator)) {
- result = a + b;
- }else {
- result = a - b;
- }
- return result;
- }
- }
-
- // 测试类
- public class Client {
- public static void main(String[] args) {
- Calculator calculator = new Calculator();
- System.out.println(calculator.operation(10, 13, "+"));
- System.out.println(calculator.operation(10, 13, "-"));
- }
- }
-
-
- 这样的设计比较死板,如果我们要实现乘除法呢?就不得不修改 Calculator 类中的 operation()方法,改变 if… else…语句的结构。 为了适应变化,使用策略模式来重新设计。
-
- 代码如下:
- [code]
复制代码
// 定义算法框架,具体的算法由子类实现
interface Operation {
public int execute(int a, int b);
}
class Add implements Operation {
public int execute(int a, int b) {
return (a + b);
}
}
class Sub implements Operation {
public int execute(int a, int b) {
return (a - b);
}
}
// 上下文 Context 类
class Calculator {
private Operation operation;
// 设置具体的算法策略
public void setOperation (Operation operation) {
this.operation = operation;
}
public int execute(int a, int b) {
return this.operation.execute(a, b);
}
}
// 测试类
public class Client {
public static void main(String[] args) {
Calculator calculator = new Calculator();
// 加法操作
calculator.setOperation(new Add());
System.out.println(calculator.execute(20, 13));
// 减法操作
calculator.setOperation(new Sub());
System.out.println(calculator.execute(20, 13));
}
}
如果此时我们需要添加乘除法,只需要再写一个实现了 Operation 接口的类,并实现其具体策略即可,在客户端即可方便地调用。下面使用枚举策略的方式来实现,代码如下:
[code][/code]
// 策略枚举
enum Calculator {
// 加法策略的实现
Add(){
public int execute (int a, int b) {
return (a + b);
}
}, // 这里用逗号隔开各个枚举变量
// 减法策略的实现
Sub(){
public int execute (int a, int b) {
return (a - b);
}
}; // 这里用逗号结束枚举变量的定义
// 定义抽象算法方法,让每个枚举变量来具体实现
public abstract int execute(int a, int b);
}
public class Client {
public static void main(String[] args) {
// 加法
System.out.println(Calculator.Add.execute(20, 13));
// 减法
System.out.println(Calculator.Sub.execute(20, 13));
}
}
使用枚举策略模式,不足是并不能像上面第二种方式那样适应变化,原因是如果要添加其他策略,同样需要修改枚举类,即添加具体的枚举变量。不过枚举策略的代码结构确实比较简洁。由于枚举策略的模式也不适合扩展,因此适合担任不会频繁发生变化的角色。
策略模式是比较简单的一个模式了,但是它也有不足之处:所有的具体策略都必须暴露给客户,否则客户怎样根据自身需要使用不同的策略呢?而且,策略模式实际上是把条件判断的逻辑(即各个条件分支,也就是每个具体策略)转移到客户端了,由客户来选择不同的具体策略。
本文出自 “蚂蚁” 博客,请务必保留此出处http://haolloyin.blog.51cto.com/1177454/343464 |
|