一、策略模式概述
策略模式用于算法的自由切换和扩展,它是使用较为广泛的设计模式之一。
策略模式实现了算法定义和算法使用的分离,它通过继承和多态的机制实现对算法族的使用和管理。
定义:
策略模式:定义一系列算法,将每一个算封装起来,并让它们可以互相替换。策略模式让算法可以独立于使用它的客户而变化。
二、策略模式的结构和实现
2.1 策略模式的结构
策略模式包含以下3个角色:
- Context(环境类):环境类是使用算法的角色,它在解决某个问题时可以采用多种策略。
- Strategy(抽象策略类):为所支持的算法声明了抽象方法,是所有策略类的父类。
- ConcreteStrategy(具体策略类):具体策略类实现了在抽象策略类中声明的算法。
2.2 策略模式的实现
//环境类
/**
* 环境类角色
* 数组操作类
*/
public class ArrayUtils {
private SortAlgorithmStrategy sortAlgorithm;
/**
* 对数组进行排序
*/
public void sortArray() {
sortAlgorithm.sort();
}
public void findArray() {
System.out.println("模拟查找数组元素");
}
public SortAlgorithmStrategy getSortAlgorithm() {
return sortAlgorithm;
}
public void setSortAlgorithm(SortAlgorithmStrategy sortAlgorithm) {
this.sortAlgorithm = sortAlgorithm;
}
}
//抽象策略类
/**
* 抽象策略类
* 排序算法策略
*/
public abstract class SortAlgorithmStrategy {
/**
* 排序算法
*/
public abstract void sort();
}
//具体策略类
/**
* 冒泡排序策略
*/
public class BubbleSortStrategy extends SortAlgorithmStrategy{
@Override
public void sort() {
System.out.println("冒泡排序算法");
}
}
/**
* 插入排序策略
*/
public class InsertionSortingStrategy extends SortAlgorithmStrategy{
@Override
public void sort() {
System.out.println("插入排序算法");
}
}
/**
* 选择排序策略
*/
public class SelectionSortStrategy extends SortAlgorithmStrategy{
@Override
public void sort() {
System.out.println("选择排序算法");
}
}
//客户端
public class Client {
public static void main(String[] args) {
/**
* 案例需求描述:
* 有一个对数组数据进行操作的类,该类封装类对数组的常见操作;
* 现对其中的排序方法可以动态的更换排序算法,增加新的排序算法也比较灵活;
* 现使用策略模式设计此功能。
*/
ArrayUtils arrayUtils = new ArrayUtils();
arrayUtils.setSortAlgorithm(new SelectionSortStrategy());
arrayUtils.sortArray();
}
}
三、策略模式的优缺点和适用环境
3.1 策略模式的优点
- 策略模式提供了对开闭原则的完美支持,灵活选择其他策略或增加新的策略行为;
- 策略模式提供了管理相关的算法族的办法;
- 策略模式提供了一种可以替换继承关系的办法;
- 策略模式可以避免多重条件选择语句;
- 策略模式提供了一种算法的复用机制;
3.2 策略模式的缺点
- 客户端必须知道所有的策略类,并自行选择使用哪一个策略类;
- 将造成系统有很多的具体策略类;
- 无法同时在客户端使用多个策略类;
3.3 策略模式的适用环境
- 一个系统需要动态地在几种算法中选择一种;
- 避免使用难以维护的多重条件选择语句
- 不希望客户端知道复杂的、与算法相关的数据结构。
【参考文献】:
本文是根据刘伟的《Java设计模式》一书的学习笔记,仅供学习用途,勿做其他用途,请尊重知识产权。
【本文代码仓库】:https://gitee.com/xiongbomy/java-design-pattern.git