设计模式06-策略模式

策略模式(Strategy Pattern)是指定义了算法家族、分别封装起来,让它们之间可以相互替换。此模式中算法的变化不会影响使用算法的用户。

示例代码

https://github.com/chenpenghui93/design-pattern/tree/master/src/main/java/com/example/designpattern/strategy

类图:

JDK实例

Comparator接口中的compare()方法就是应用策略模式的一个实例:

1
2
3
4
5
public interface Comparator<T> {
...
int compare(T o1, o2);
...
}

Comparator接口有许多实现类,开发中会将Comparator作为参数传入作为排序策略,例如Arrays类的parallelSort方法、TreeMap的构造方法等

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class Arrays {
...
public static <T> void parallelSort(T[] a, Comparator<? super T> cmp) {
if (cmp == null)
cmp = NaturalOrder.INSTANCE;
int n = a.length, p, g;
if (n <= MIN_ARRAY_SORT_GRAN ||
(p = ForkJoinPool.getCommonPoolParallelism()) == 1)
TimSort.sort(a, 0, n, cmp, null, 0, 0);
else
new ArraysParallelSortHelpers.FJObject.Sorter<>
(null, a,
(T[])Array.newInstance(a.getClass().getComponentType(), n),
0, n, 0, ((g = n / (p << 2)) <= MIN_ARRAY_SORT_GRAN) ?
MIN_ARRAY_SORT_GRAN : g, cmp).invoke();
}
...
}
1
2
3
4
5
6
7
8
9
10
11
public class TreeMap<K,V>
extends AbstractMap<K,V>
implements NavigableMap<K,V>, Cloneable, java.io.Serializable
{
...
public TreeMap(Comparator<? super K> comparator) {
this.comparator = comparator;
}
...

}

Spring实例

  • Resource接口下有ContextResource、BeanDefinitionResource、InputStreamResource等实现类,根据不同需要选择不同的实现类

  • Spring的初始化也使用了策略模式,不同类型的类采用不同的初始化策略, InstantiationStrategy接口下有两种实现策略,类图如下:

适用场景

  • 系统中有很多类,这些类的区别仅仅在于他们的行为不同
  • 一个系统需要动态地在几种算法中选择一个

模式优点

  • 策略模式符合开闭原则
  • 避免使用多重条件转移语句,如if…else…语句、switch语句
  • 使用策略模式可以提高算法的保密性和安全性

模式缺点

  • 客户端必须知道所有的策略类,并且自行决定使用哪一个策略类
  • 代码中会产生非常多的策略类,增加维护难度

参考