简介
为什么要使用策略模式
在软件开发中,实现一个功能可能有多种方式,每一种方式称为一种策略。如何管理这些策略是个问题,策略模式就是为了解决这个问题产生的。
什么是策略模式
策略模式(Strategy Pattern):定义一系列算法,将每一个算法封装起来,并让它们可以相互替换。策略模式让算法独立于使用它的客户而变化。
别名
政策模式(Policy)
类型
对象行为型模式
遵守的原则
开闭原则。
使用频率
★★★★☆
角色
角色
- Context: 上下文类
- 具体类
- 选择策略解决问题(通过一个ConcreteStrategy对象来配置)。
- 维持着一个抽象策略类Strategy的引用。
- Strategy: 抽象策略类
- 具体类/抽象类/接口
- 具体策略类的父类。
- 定义所有支持的算法的接口。Context使用这个接口来调用某个ConcreteStrategy定义的算法。
- ConcreteStrategy: 具体策略类
- 具体类
- 抽象策略类Strategy的子类。
- 每个策略类对应一种策略。
UML类图
时序图
待补充。
实现
- 新建环境类Context.java
- 新建抽象策略类Strategy.java
- 新建具体策略类ConcreteStrategyA.java、ConcreteStrategyB.java
- 创建测试类Client.java
环境类Context.java
class Context {
// 维持一个对抽象策略类的引用
private Strategy strategy;
public void setStrategy(Strategy strategy) {
this.strategy = strategy;
}
// 调用策略类
public void algorithm() {
strategy.algorithm();
}
}
抽象策略类Strategy.java
abstract class Strategy {
// 声明抽象算法
public abstract void algorithm();
}
具体策略类
ConcreteStrategyA.java
class ConcreteStrategyA extends Strategy {
// 算法的具体实现
@Override
public void algorithm() {
System.out.println("使用策略A");
}
}
ConcreteStrategyB.java
class ConcreteStrategyB extends Strategy {
// 算法的具体实现
@Override
public void algorithm() {
System.out.println("使用策略B");
}
}
测试
运行Client.java的main()
public class Client {
public static void main(String[] args) {
Context context = new Context();
ConcreteStrategyA concreteStrategyA = new ConcreteStrategyA();
context.setStrategy(concreteStrategyA);
context.algorithm();
}
}
测试类
Client.java
使用策略A
使用策略B
优缺点
优点
- 遵守“开闭原则”。客户端可以在不修改原有系统的条件下灵活的新建新的策略。
缺点
- 待补充
适用环境
- 实现一个功能有多种方式,要求可以灵活的选择这些实现方式。
使用场景
- 待补充
扩展
- 享元模式Flyweight:Strategy对象经常是很好的轻量级对象。
问题
在软件开发中,你在哪里用到了策略模式?
待补充。