- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
深入浅出策略模式
深入浅出策略模式
一、引子
跟不同类型的MM约会,要用不同的方法,有的请电影比较好,有的则去吃小吃效果不错,有的去海边浪漫最合适,但目的都是为了得到MM的芳心……哦……打住!!!其实这也就是对不同情况所采取的不同的策略。这种情况在实际软件开发中也是经常遇到,那么你是怎么来实现不同的策略的呢?看了策略模式后应该会有一些感想吧!
二、定义和结构
策略模式(Strategy Pattern)属于对象行为型设计模式,主要是定义一系列的算法,把这些算法一个个封装成拥有共同接口的单独的类,并且使它们之间可以互换。策略模式使这些算法在客户端调用它们的时候能够互不影响地变化。这里的算法不要狭义的理解为数据结构中算法,应该理解为不同的业务处理方法。
这种做法会带来什么样的好处呢?
它将算法的使用和算法本身分离,即将变化的具体算法封装了起来,降低了代码的耦合度,系统业务策略的更变仅需少量修改。
算法被提取出来,这样可以使算法得到重用,这种情况还可以考虑使用享元模式来共享算法对象,来减少系统开销(但要注意使用享元模式的建议条件)。
先看看策略模式的结构:要使算法拥有共同的接口,就要实现一个接口或者一个抽象类出来才行。这样结构的轮廓也就出来了,可用简单的类图来表示它们之间的关系:
策略模式由三个角色组成:
算法使用环境角色:算法被引用到这里和一些其它的与环境有关的操作一起来完成任务;
抽象策略角色:规定了所有具体策略角色所需的接口。在java它通常由接口或者抽象类来实现;
具体策略角色:实现了抽象策略角色定义的接口。
三、使用策略模式的程序优化案例
让我们看看一家软件公司是如何通过策略模式,改进自己的游戏设计的。
这个游戏先前推出过一款非常成功的小鸭池塘游戏——SimUDuck,里面有各种各样的鸭子,它们在池塘里欢快地游来游去,还会嘎嘎叫。游戏虽然简单,但可玩性高,因此很受欢迎。该游戏最初是用标准的OO方式进行设计实现的:有一个超类Duck,而各种具体类型的鸭子都继承该类。请看设计类图:
但现在情况有所变化,公司面临的竞争越来越激烈,许多类似的产品已在市场上出现。经过一个星期的头脑风暴过程以后,公司高层决定对游戏进行重大变革,至少要在即将召开的董事会上给股东们留下深刻的印象。
公司总裁已经想好了,新游戏的创意要点在于使PC显示屏上的小鸭子能够飞起来,小鸭翅膀扇起的风暴将把竞争对手的类似的模拟游戏吹得远远的。设计师Joe觉得这也没什么困难的,毕竟这还是一个OO软件,完全可以再次展示自己的OO设计天赋,于是下列设计就产生了:
但到了董事会那天,出大事了;现场演示的时候一种特殊的“鸭子”——橡皮鸭子(Rubber Duck)也在屏幕上飞来飞去,笑得股东们前仰后合,但笑完之后就是严厉地指责:我们开发的到底是款什么游戏?公司是不是想改名叫怪物公司(M)了?
面对这个问题,Joe不得不低下高贵的头,承认这个设计有个小缺陷,自己忘了不是所有的Duck的子类都能飞;而fly( )方法放在超类Duck中,结果所有的子类都获得了该方法。其实Joe的设计背后有明确的目标,即通过继承实现功能的复用,但这种做法却为设计的维护提出了难题。
Joe马上改正错误的设计,并且为了不再犯错误,他对许多问题开始未雨绸寥了。首先,他使RubberDuck类重载了fly( )方法,这样橡皮鸭子就不会飞了,但仍然会嘎嘎叫。还有一种特殊的“鸭子”——猎人打猎用的诱饵鸭子,因此这种“鸭子”既不会飞,也不能叫(它一张嘴可就露馅了,野鸭子立刻会明白这不是我兄弟),于是超类Duck中的Quack( )方法也必须被重载,这两个类的类图如下:
Joe已经意识到了一个问题:这样的层次架构不能对付各种可能出现的设计变化。Joe拿到手的备忘录上提到过,总裁们决定每六个月就将产品升级一次(尽管升级的方式他们还没想好)。Joe知道在这个小鸭游戏中,鸭子的种类会不断变化,其fly( )和quack( )方法会不断变化,这将迫使Joe不得不多次重载这两个方法,而且该过程将永远保持下去……,这种感觉让Joe觉得很不爽。于是他决定使用接口(interface)这种高级特征改进相关类的层次架构:
这个层次架构看起来很不错,使用了继承、接口(自然就有多态性)等OO设计方法,许多国内讲解OO程序设计的书籍的认识深度也不过如此了。但这样就真的是好的设计了吗?
事实上,这个设计堪称愚蠢到了极点。尽管看起来避免了fly( )和quack( )等少数方法的重载,但却导致了灾难性的“代码重复”问题。试想,如果有100种小鸭子,由于它们都需要具体实现fly( )、quack( )等方法,那么由于其中90多种小鸭子的fly( )方法代码都相同,或大致相同,那么就需要把这些大同小异的代码在子类中复制90多遍,程序员面对这种编程效果,真是情何以堪!
原创力文档


文档评论(0)