策略模式
1. 介绍
策略模式(Strategy Pattern)
是一种行为型模式。定义一系列的算法,把它们一个个封装起来,并且使得它们可以相互替换,使得算法可以独立于使用它的客户而变化。
例子:常见的排序方法有冒泡排序、插入排序、归并排序、希尔排序等,而某个类需要使用一种排序方法,你可以将这些排序方法分别封装到类中,这些类都需要实现一个 Strategy 接口。在需要使用某种算法的类中,替换其中内嵌的 Strategy 对象就可以实现排序方法的替换。
优点
- 实现的选择。用户可以根据不同的情况采用不同的算法。
- 可扩展。增加新的算法,创建 Strategy 接口的新的实现类就可以了。
- 封装性。算法的实现细节都封装在类中,使用者只需使用即可,无需关注其实现的过程和细节。
缺点
- 增加了类的数量。一个算法需要一个类,算法数量的增加势必会导致类数量的增加。
- Strategy和Context类之间的通信开销。算法的增多可能会导致 Strategy 接口参数的增多,而这会导致 Strategy 和 Context 的耦合度增大。
2. 例子
有一个 Strategy 接口,它有两个实现类,一个是 addStrategy,代表的是加法策略,另一个是 SubStrategy,代表的是减法策略。有一个使用了 Strategy 的类 Context,其中的方法是使用其 Strategy 类型的 strategy 属性实现的,所以,更换其中的 strategy 就可以更换方法中使用的算法。
类图:
Strategy接口
策略接口,具体的策略需要实现这个接口。
package strategyPattern;
/**
* 策略接口
*
* @author jxd
* @since 2021-06-14
*/
public interface Strategy {
public int doOperation(int num1, int num2);
}
addStrategy类
代表的是加法策略,实现了 Strategy 接口。
package strategyPattern;
/**
* 加法策略
*
* @author jxd
* @since 2021-06-14
*/
public class addStrategy implements Strategy {
/**
* 执行加法操作
*/
@Override
public int doOperation(int num1, int num2) {
return num1 + num2;
}
}
SubStrategy类
代表的是减法策略,实现了 Strategy 接口。
package strategyPattern;
/**
* 减法策略
*
* @author jxd
* @since 2021-06-14
*/
public class SubStrategy implements Strategy {
@Override
public int doOperation(int num1, int num2) {
return num1 - num2;
}
}
Context类
一个使用了 Strategy 对象的类,更换其中的 Strategy 对象就可以更改使用的算法。
package strategyPattern;
/**
* 上下文,一个使用了Strategy的类
* @author jxd
* @since 2021-06-14
*/
public class Context {
/**
* 使用的策略
*/
private Strategy strategy;
public Context(Strategy strategy) {
this.strategy = strategy;
}
/**
* 调用策略中的方法
* @param num1 第一个数
* @param num2 第二个数
* @return 返回根据策略中的方法执行的结果
*/
public int doOperation(int num1, int num2) {
return strategy.doOperation(num1, num2);
}
}
测试类:
package strategyPattern;
import org.junit.Test;
/**
* 策略模式的策略类
*
* @author jxd
* @since 2021-06-14
*/
public class TestJ {
@Test
public void test1() {
Context context1 = new Context(new addStrategy());
System.out.println("使用加法策略计算1+1的结果为:" + context1.doOperation(1, 1));
Context context2 = new Context(new SubStrategy());
System.out.println("使用减法策略计算1+1的结果为:" + context2.doOperation(1, 1));
}
}
运行结果:
使用加法策略计算1+1的结果为:2
使用减法策略计算1+1的结果为:0
3. 总结
定义一系列的算法,把它们一个个封装起来,并且使得它们可以相互替换,使得算法可以独立于使用它的客户而变化。