定义:基本含义是针对一组算法或者行为特性,将他们抽象到具有共同接口函数的独立抽象类后者接口中,从而使得他们可以相互替换。这样就使得某一个特定的接口行为可以在不影响客户端的情况下发生变化。
类型:行为类模式
类图:
策略模式是对算法的封装,把一系列的算法分别封装到对应的类中,并且这些类实现相同的接口,相互之间可以替换。调用算法的主体则是封装到了封装类Context中,抽象策略Strategy一般是一个接口,目的只是为了定义规范,里面一般不包含逻辑。其实,这只是通用实现,而在实际编程中,因为各个具体策略实现类之间难免存在一些相同的逻辑,为了避免重复的代码,我们常常使用抽象类来担任Strategy的角色,在里面封装公共的代码。
策略模式的结构:
- 环境角色context:也叫上下文,对策略进行二次封装,目的是避免高层模块对策略的直接调用。将制有一个Strategy类的引用,将决定调用哪种Strategy角色完成业务逻辑。
- 抽象策略Strategy:通常情况下为一个接口,当各个实现类中存在着重复的逻辑时,则使用抽象类来封装这部分公共的代码。这个角色是策略模式的核心,他是所有策略算法的核心归纳。
- 具体策略(ConcreteStrategy):具体策略角色通常由一组封装了算法的类来担任,这些类之间可以根据需要自由替换。
策略模式的核心是对算法的包装,最终目的是把使用算法的责任(环境)和算法实现进行解耦。由于环境和算法的独立,算法的增加,修改都不会影响到环境。
客户端环境(Context)必须知道所有的策略类、理解这些不同策略算法之间的区别,并自行决定使用哪一个策略类来完成业务逻辑。
适用场景
做面向对象设计的,对策略模式一定很熟悉,因为它实质上就是面向对象中的继承和多态,至少在在以下两种情况下,大家可以考虑使用策略模式,
- 几个类的主要逻辑相同,只在部分逻辑的算法和行为上稍有区别的情况。
- 有几种相似的行为,或者说算法,客户端需要动态地决定使用哪一种,那么可以使用策略模式,将这些算法封装起来供客户端调用。
struts2应用策略模式的例子:
Dispatcher进行初始化第二步,主要是完成对配置元素的加载器的初始化工作。请看图
这些配置加载器的具体实现核心,是一个针对不同数据格式的配置元素的读取过程。由于配置的形式是多种多样的,这就导致了读取配置的算法也各不相同。
在这里,无论有多少中策略实现,只要他们的行为特征是一样的,可以从中获取策略实现的结果并加以处理。
策略实现可以任意进行了灵活的扩展,而对客户端调用者而言则是透明的。
这部分的代码请参考前面的文章。