设计模式十六之策略模式
策略模式
 策略(strategy)模式属于对象的行为模式。其用途是针对一组算法,将每个不同算法封装到具有共同接口的独立类中,从而使他们可以相互替换。即使 算法和对象分开来,使得算法可以独立于使用它的客户而变化。
场景
某个市场人员接到单后的报价策略。报价策略很复杂,可以简单作如下分类:
- 新客户小批量,不打折
 - 新客户大批量,打9折
 - 老客户小批量,打8.5折
 - 老客户大批量,打8折
 
通常使用if…else或者switch…case进行表示,代码如下:
1  | package designMode.strategy;  | 
这样实现起来比较简单,符合一般开人员的思路,但是当类型特别多,算法比较复杂时,整个条件控制代码会变得很长,难于维护。这时我们可以采用策略模式,将不同的策略分开,委派给不同的对象管理。
模式结构
结构图

- Context环境角色 : 持有一个Strategy的引用。
 - Strategy抽象策略角色: 这是一个抽象角色,通常由一个接口或抽象类实现。此角色给出所有的具体策略类所需的接口。
 - ConcreteStrategy具体策略角色: 包装了相关的算法或行为。
 
代码
Strategy抽象策略角色:
1  | package designMode.strategy;  | 
ConcreteStrategy具体策略角色
1  | public class NewCustomerSmallStrategy implements Strategy {  | 
1  | public class NewCustomerBigStrategy implements Strategy {  | 
1  | public class OldCustomerSmallStrategy implements Strategy {  | 
1  | public class OldCustomerBigStrategy implements Strategy {  | 
Context环境角色
1  | public class Context {  | 
客户端
1  | package designMode.strategy;  | 
控制台
1  | 小客户大批量  | 
从上面的示例可以看出,策略模式仅仅封装算法,提供新的算法插入到已有系统中,以及老算法从系统中“退休”的方法,策略模式并不决定在何时使用何种算法。在什么情况下使用什么算法是由客户端决定的。
总结
优点
- 策略模式提供了管理相关的算法族的办法。策略类的等级结构定义了一个算法或行为族。恰当使用继承可以把公共的代码移到父类里面,从而避免代码重复。
 - 使用策略模式可以避免使用多重条件(if-else)语句。多重条件语句不易维护,它把采取哪一种算法或采取哪一种行为的逻辑与算法或行为的逻辑混合在一起,统统列在一个多重条件语句里面,比使用继承的办法还要原始和落后。
 
缺点
- 客户端必须知道所有的策略类,并自行决定使用哪一个策略类。这就意味着客户端必须理解这些算法的区别,以便适时选择恰当的算法类。换言之,策略模式只适用于客户端知道算法或行为的情况。
 - 由于策略模式把每个具体的策略实现都单独封装成为类,如果备选的策略很多的话,那么对象的数目就会很可观。
 
行为模式
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 YD Blog!