策略模式是对算法的封装,把一系列的算法分别封装到对应的类中,并且这些类实现相同的接口,相互之间可以灵活地替换.(不修改原代码)
- Context(环境类):
使用算法的角色,它在解决某个问题(即实现某个方法)时可以采用多种策略。在环境类中维持一个对抽象策略类的引用实例,用于定义所采用的策略,在运行时调用具体策略类中的方法.
- Strategy(抽象策略类):
为所支持的算法声明了抽象方法,是所有策略类的父类,它可以是抽象类或具体类,也可以是接口.
- ConcreteStrategy(具体策略类):
实现了在抽象策略类中声明的算法,在运行时,具体策略类将覆盖在环境类中定义的抽象策略类对象,使用一种具体的算法实现某个业务处理.
模板方法也是对不同算法的实现封装到不同的子类中,在开发过程中这两种方法也经常混用.
硬要区分的话还是有的:
- 模板方法更注重代码的复用(一般抽象类需是Abstract Class),定义与实现耦合,策略模式更注重策略(不同子类)的选择(抽象类一般是Interface,当然也可以是Abstract Class)将定义与实现分离.
- 模板方法模式的算法调用主体在抽象父类中(即
模板方法
的步骤组合),策略模式的算法调用主题在Context类中
-
一个系统需要动态地在几种算法中选择一种,那么可以将这些算法封装到一个个的具体算法类中,而这些具体算法类都是一个抽象算法类的子类,满足里氏替换原则.
-
一个对象有很多的行为,如果不用恰当的模式,这些行为就只好使用多重条件选择语句来实现.此时,使用策略模式,把这些行为转移到相应的具体策略类里面,就可以避免使用难以维护的多重条件选择语句,使其满足单一职责原则.
-
不希望客户端知道复杂的、与算法相关的数据结构,在具体策略类中封装算法与相关的数据结构,可以提高算法的保密性与安全性.
-
易于扩展,增加一个新的策略对策略模式来说非常容易,基本上可以在不改变原有代码的基础上进行扩展.满足“开闭原则”.
-
具体策略类之间可以自由切换.
-
避免使用落后的多重条件选择语句.
-
提供了一种算法的复用机制,可将算法单独提取出来封装在抽象策略类中,不同的环境类可以方便地复用这些算法。
-
客户端需要知道所有的具体策略类并自行选择.
-
系统产生多个具体策略类,每个细小的改动豆浆增加一个新的具体策略类.
具体策略类过多也增加了维护的难度.