策略模式是一种很简单的基础模式,用于封装一系列算法,使客户端的访问独立于算法的实现。我们可以”井中取水”来形象的描述策略模式。“取水”是一个动作,完成这个动作的方式有很多中,可以直接用手提、可以用水车汲水、也可以用电泵抽水。在不同的环境和条件下,我们选择不同的取水方式,这就是策略模式。
策略模式的应用场景
1,有大量动作相同实现不同的行为模式需要配置,以使在适当的环境下选择恰当的行为。
2,算法或实现需要一系列不同的变量。同样的行为在不同的前提下产生不同的结果。
3,有复杂的算法、数据结构或实现需要对客户端隐藏。
UML图
解释
Context 用于封装和隐藏策略,客户端访问 Context 类来完成策略的调用。一般用来存储环境参数,为算法的选择提供依据。
Strategy 策略基类。用于提供策略接口。
ConcreteStrategy 策略的具体实现类,封装各自的算法。
Context 和 Strategy 的交互来完成算法的选择。可以在策略类调用时传入算法所需的参数,也可以将Context作为参数传入算法,让算法在内部自己决定需要那些参数。
一般客户端实例化Strategy然后传入 Context 中,然后客户端与 Context 交互。
代码
略。。。
总结
1,策略模式适用于动作单一,即能抽象出较简单的统一接口的情形。
2,策略模式是一大堆算法的封装。策略模式提供统一的接口访问大量不同的策略算法。
3,如果策略需要的外部参数极少,则可以直接继承Strategy。
继承同样提供了统一接口的封装特性,但是没有Context的情况下,策略的环境参数和具体实现被揉在一起,让策略集合更难维护。某些情况下甚至无法抽象出统一的接口。
4,策略模式有助于消除代码中的条件选择。我们知道,代码中大量出现的 if else 和 switch case ,让维护变得更加困难。策略模式对于消除这种现象非常有帮助 。
5,策略模式可以让我们在不同算法中选择一个有利的实现,但前提是客户端需要知道所有的策略。比如WPF的 Brush就有许多不同的实现,要正确使用Brush,需要了解系统提供的brush类型。
6,不同的策略需要不同的参数,Context 需要提供的参数可能过多。客户端在使用 Context 的时候就可能需要配置大量参数,同时也谁增加Context 和 Strategy的耦合度。
7,类型系统膨胀。策略模式导致增加大量子类。