策略模式
1、策略模式的动机
- 完成一项任务有多种途径,每一种途径称之为一个策略,我们可以根据环境或条件来选择一种途径来完成任务;
- 实现某个功能可以由多种方式,此时需要使用一种设计模式能够方便的选择,增加或删除某种方式。
2、策略模式的定义
策略模式(Strategy Pattern):定义一系列算法,将每一个算法封装起来,并让它们可以相互替换。策略模式让算法独立于使用它的客户而变化, 也称为政策模式(Policy)。策略模式是一种对象行为型模式
3、策略模式的类结构图
分析如下:
- 客户端来决定使用什么策略;
- 策略模式仅仅封装算法和提供新算法插入到系统中以及老算法从系统中移除,并不决定客户端使用哪种算法。相对应的客户端需要了解所有的算法 以及选择哪种算法,相应的增加了客户端的难度;
4、优缺点和适用场景
优点:
- 对”开闭原则”良好的支持,用户可以在不改变原有系统的情况下选择算法,也可以灵活的增加删除算法;
- 提供管理算法簇的方法;
- 提供了可以替换继承关系的办法;
- 可以避免使用多重if-else的方法;
缺点:
- 客户端必须知道所有的策略,并自行决定使用哪一个;
- 策略模式将产生很多的策略,可以通过享元模式一定程度上减少策略的数量;
适用场景:
- 如果在一个系统里面有许多类,它们之间的区别仅在于它们的行为,那么使用策略模式可以动态地让一个对象在许多行为中选择一种行为;
- 一个系统需要动态地在几种算法中选择一种;
- 如果一个对象有很多的行为,如果不用恰当的模式,这些行为就只好使用多重的条件选择语句来实现;
- 不希望客户端知道复杂的、与算法相关的数据结构,在具体策略类中封装算法和相关的数据结构,提高算法的保密性与安全性;
5、实例
例:多重排序算法策略;
策略抽象类:
public interface SortStrategy {
int[] sort(int[] a);
}
选择排序算法:
public class SelectSortStrategy implements SortStrategy {
public int[] sort(int[] a) {
if (a == null || a.length == 0) {
return a;
}
int t;
for(int i = 0; i < a.length-1; i++) {
for(int j = i + 1; j < a.length; j++) {
if (a[i] > a[j]) {
t = a[i];
a[i] = a[j];
a[j] = t;
}
}
}
return a;
}
}
插入排序:
public class InsertSortStrategy implements SortStrategy {
public int[] sort(int[] a) {
if (a == null || a.length == 0) {
return a;
}
for(int i = 1; i < a.length; i++) {
int t = i;
int m = a[i];
for(int j = i - 1; j >= 0; j--) {
if (a[j] > m) {
a[j + 1] = a[j];
t--;
}
}
a[t] = m;
}
return a;
}
}
环境类:
public class StrategyContext {
private SortStrategy sortStrategy;
public void setSortStrategy(SortStrategy sortStrategy) {
this.sortStrategy = sortStrategy;
}
public int[] sort(int[] a) {
return sortStrategy.sort(a);
}
}
测试
public class Test {
public static void main(String[] args) {
StrategyContext strategyContext = new StrategyContext();
strategyContext.setSortStrategy(new SelectSortStrategy());
int[] a = { 3, 23, 12, 43, 123, 1 };
a = strategyContext.sort(a);
for(int b : a) {
System.out.println(b);
}
}
}