1. 策略模式(Strategy Pattern)
Define a family of algorithms, encapsulate eache one, and make them interchangeable. (定义一组算法, 将每个算法都封装起来,并使它们之间可以相互替换)
策略模式是一种非常简单的模式,核心就是面向接口编程. 只是粒度更小,将每种算法都单独成一个策略类. 策略模式有点儿类似于java8的函数式接口,可以将函数当做参数传递.
1.1 核心思想
- 将算法(可变部分)抽处理单独成一个策略类, 使不同的算法可以自由切换
- 策略模式其实就是面向接口编程的一种体现,只是将算法封装成了一个独立的类而已.
- 策略模式体现了几个设计原则:
- 把易变化的代码抽离出来,单独成类
- 针对接口编程,而不是针对具体类编程.(策略接口)
- 多用组合/聚合, 少用继承
1.2 策略模式-类图
- Strategy: 抽象策略角色. 定义算法抽象方法. 通常一个策略接口中只定义一个算法
- ConcreteStragy: 具体策略角色. 实现算法逻辑
- Context: 封装角色, 起承上启下左右. 屏蔽高层模块儿对策略,算法的直接访问,封装可能的变化.
1.3 策略模式-优缺点
- 优点:
- 算法可以自由切换
- 避免多重条件判断
- 扩展性好: 新增算法实现时,新增一个策略即可
- 缺点:
- 策略类数量增多. 通常策略类遵守轻量化原则,一个策略便是一个类,因此会导致类的数量激增.
- 所有策略类都需要向外暴露. 上层模块儿必须清晰知道每个策略类的特性,然后自行选择使用的策略类.
- 违背迪米特法则
1.4 策略模式-适用场景
- 多个类只有在算法或行为上稍有不同的场景
- 算法需要自由切换的场景
- 需要屏蔽算法规则实现细节的场景
- jdk中集合的Compare方法便是一种策略模式
2. 策略模式-应用示例
策略模式主要是用来抽象算法的,那么我们就来模拟一个算法的例子. 我们指定排序算法有很多种,简单排序,快速排序,冒泡排序等, 我们将每种排序方式抽象为策略
2.1 类图
2.2 排序策略抽象接口-ISortStrategy
只定义一个抽象方法sort()
public interface ISortStrategy {
void sort();
}
2.3 简单排序-SimpleSort
算法实现并不是本篇博客的重点,因此直接输出一条语句即可
public class SimpleSort implements ISortStrategy {
@Override
public void sort() {
System.out.println("使用简单排序进行排序...");
}
}
2.4 冒泡排序-BubbleSort
算法实现并不是本篇博客的重点,因此直接输出一条语句即可
public class BubbleSort implements ISortStrategy {
@Override
public void sort() {
System.out.println("使用冒泡排序进行排序...");
}
}
2.5 快速排序-QuickSort
算法实现并不是本篇博客的重点,因此直接输出一条语句即可
public class QuickSort implements ISortStrategy {
@Override
public void sort() {
System.out.println("使用快速排序进行排序...");
}
}
2.6 排序上下文-SortContext
- 此类的存在,让策略模式有点儿类似于java8的函数式接口,可以将方法当做参数传递.
public class SortContext {
private ISortStrategy sortStrategy;
public SortContext(ISortStrategy sortStrategy) {
this.sortStrategy = sortStrategy;
}
public void doSort(){
// 可以做一些其它逻辑操作
System.out.println("排序前先过滤为空数据...");
this.sortStrategy.sort();
}
}
2.7 测试
客户端调用时,需要清楚每种策略的特点,然后选择特定的排序进行调用.
@Test
public void test(){
SortContext sortContext ;
// 使用简单排序
sortContext = new SortContext(new SimpleSort());
sortContext.doSort();
// 使用冒泡排序
sortContext = new SortContext(new BubbleSort());
sortContext.doSort();
// 使用快速排序
sortContext = new SortContext(new QuickSort());
sortContext.doSort();
}