一、借鉴说明
1.《Head First Design Patterns》(中文名《深入浅出设计模式》)
2.*,策略模式,https://zh.wikipedia.org/wiki/%E7%AD%96%E7%95%A5%E6%A8%A1%E5%BC%8F
二、策略模式(Strategy Pattern)
- 基础知识
将一类相同的算法封装起来,形成算法族,只提供相同的接口给外界,同一算法族内的算法可以互相替换,外界使用时,没有感觉什么不同,即算法族内的算法独立于使用者存在。
- 具体例子
学生Student和老师Teacher去学校School的方式有很多种:坐公交Bus,坐地铁Subway,坐车Car等等。
因此就有了第一种情况:Student有goToSchoolByBus、goToSchoolBySubway、goToSchoolByCar函数,Teacher也有goToSchoolByBus、goToSchoolBySubway、goToSchoolByCar函数,UML如图所示。但是这样太过冗余,这里的冗余具体是指:"搭乘交通工具的方式"是可以共用的部分,不管是Student还是Teacher都是可以坐Bus、Subway、Car的。还有就是不灵活,如果以后突然有别的需求的话,例如走路Walk去学校的话,那么Student和Teacher就要分别修改了,费时费力,还有可能带来副作用(如出现意想不到的bug),因此,需要把可能变化的部分提取出来,将这部分做成算法族。
因此,改进上述情况:Student、Teacher都有goToSchool函数,并持有一个IWay接口的引用,而将Bus、Subway、Car等相关的算法封装在IWay这一算法族里。这样,方便统一管理,方便外界的统一调用,而且需要新增算法的时候,只需要修改Way,并不影响原先的Student、Teacher。而且,也方便复用,假设有这样的一种情况,studentA有眼疾,需要导盲犬dogA的帮助才能goToSchool,这时,Dog也拥有了goToSchool这一函数,也持有了一个IWay接口的引用。UML如图所示:
- 什么时候可以考虑使用策略模式
代码里有会变化的部分,且该部分可以被提取出来(尽量使用"面向接口",这样有利于解耦)
- 具体的C#实现
设计模式(C#)的相关代码我都放在git上:https://github.com/MGKING3/DesignPatternsUseCSharp
我使用的是VS2015,是整一个项目,下载即可以用,不时更新。该模式的相关CS文件是TestStrategyPattern
- 相关OO原则
1.封装原则
2.多用组合(has-a),少用继承(is-a)
3.尽量"面向接口"