文章目录
- 描述
- 定义
- 类型
- 动机
- UML类图
- 时序图
- 实现
- 主要角色
- 示例
- 适用场景
- 优点
- 缺点
- 相关模式
描述
定义
定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。称为政策模式(Policy)。
类型
对象行为型模式
动机
在有多种算法相似的情况下,使用if…else所带来的复杂和难以维护。将这些算法封装成一个一个的类,使得客户端可以根据外部条件任意选择不同策略来解决不同问题。
UML类图
时序图
实现
主要角色
- Strategy:策略接口
- 定义所有支持的算法的公共接口。Context使用这个接口来调用某ConcreteStrategy定义的算法。
- ConcreteStrategy:具体策略
- 实现Strategy接口的某具体算法。
- Context:上下文
- 用一个ConcreteStrategy对象来配置。
- 维护一个对Strategy对象的引用。
- 可定义一个接口来让Strategy访问它的数据。
示例
-
Strategy:策略接口。当算法被调用时,Context可以将该算法所需要的所有数据都传递给该Strategy。或者,Context可以将自身作为一个参数传递给Strategy操作。这就让Strategy在需要时可以回调Context获取数据。
interface Strategy { void algorithm(Context context); }
-
ConcreteStrategy:具体策略
public class ConcreteStrategyA implements Strategy { @Override void algorithm(Context context) { System.out.println("策略 A"); } } public class ConcreteStrategyB implements Strategy { @Override void algorithm(Context context) { System.out.println("策略 B"); } }
-
Context:上下文
public class Context { private Strategy strategy; public void setStrategy(Strategy strategy) { this.strategy = strategy; } public void algorithm() { strategy.algorithm(this); } }
-
Client:客户类。客户通常创建并传递一个ConcreteStrategy对象给该Context;这样,客户仅与Context交互。在策略模式中,应当由客户端自己决定在什么情况下使用什么具体策略。
public class Client { public static void main(String[] args) { Context context = new Context(); context.setStrategy(new ConcreteStrategyA()); context.algorithm(); context.setStrategy(new ConcreteStrategyB()); context.algorithm(); } }
适用场景
- 如果系统中有许多类之间的区别仅在于它们的行为,而系统需要动态地在其中选择一种。
- 一个类中以多个条件语句的形式定义了多种行为。
- 不希望客户端知道复杂的、与算法相关的数据结构,在具体策略类中封装算法和相关的数据结构,提高算法的保密性与安全性。
优点
- 可重用的算法系列。Strategy类层次为Context定义了一系列的可供重用的算法或行为。继承有助于析取出这些算法中的公共功能。
- 一个替代继承的方法,易于切换、易于扩展。将算法封装在独立的Strategy类中使得你可以独立于其Context改变它。
- 消除了多重条件判断。将行为封装在一个个独立的Strategy类中消除了这些条件语句。
- 符合开闭原则。用户可以在不修改原有系统的基础上选择算法或行为,也可以灵活地增加新的算法或行为。
缺点
- 客户必须了解不同的Strategy。客户要选择一个合适的Strategy就必须知道这些Strategy到底有何不同。此时可能不得不向客户暴露具体的实现问题。
- Strategy和Context之间的通信开销。无论各个ConcreteStrategy实现的算法是简单还是复杂,它们都共享Strategy定义的接口。因此很可能某些ConcreteStrategy不会都用到所有通过这个接口传递给它们的信息;简单的ConcreteStrategy可能不使用其中的任何信息。
- 增加了类的数目。可以通过使用享元模式在一定程度上减少对象的数量。
相关模式
- Flyweight:Strategy对象经常是很好的轻量级对象。
发布评论