- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
完整的系统类图 - Read
The Strategy Pattern(策略模式) 问题。。。 新的需求总是可能随时出现。能否设计这样的系统,它能够方便地添加新的功能,而不至于导致对系统的重大修改。 灾难往往是由短期未臻最优的决策累积而成。在软件开发方面,不考虑长远问题的设计往往导致维护和开发的灾难。 软件开发时忽视维护性的原因 确实无法预测新需求如何变化 如果我们试图预测需求的变化,则可能会在分析阶段止步不前。 如果我们想把软件编写的能够方便的添加新功能,则可能在设计阶段止步不前。 我们没有这样做的预算 进度所逼,客户要求立即实现。 我们以后会考虑这个问题。 应对策略 在设计时考虑变化。不是准确地预测变化的性质,而是假设变化会出现,并尝试预测其出现的位置。 基于这一考虑的设计原则就是: 针对接口编程,而不是针对实现编程 优先考虑使用对象组合,而不是类继承 分离变化,进行封装 鸭塘游戏 Joe所在的电脑游戏公司研发了一款游戏软件,模拟池塘中各种鸭子嬉戏(游动并且鸣叫)的场景。软件很受欢迎。 开始时游戏的设计者采用了标准的面向对象技术 新的需求 游戏上市后的次年,竞争越来越激烈。 在外出度假一周后,公司高管们决定要对游戏作重大创新,在下周的股东大会上,他们要让股东们“印象深刻”。 杀手锏 高管们觉得,如果鸭子能够飞起来,则能击败同类游戏的竞争者。 Joe的上司告诉高管们,Joe可以在一周内搞定,因为他是一个 OO Programmer… Joe的解决方案 但是,一周后Joe的经理从股东大会上打来电话… Joe,我在股东大会上,刚刚演示了游戏,他们看到屏幕上有许多橡皮玩具鸭子在飞来飞去,你是不是故意搞笑?! 失败 小样,这叫个性! 呵呵,说实话,是偶的错,偶忘了不是所有的鸭子都会飞!在Duck中增加一个fly()方法,则它的所有子类就都有飞的能力了。没想到,一个局部的修改产生了非局部的副作用。 怎么办? 有办法了 在子类RubberDuck中重写fly()方法,让它什么都不做。还有,橡皮鸭也不会嘎嘎叫,只会吱吱叫,这样quack()方法也要改写。 但是,如果考虑再增加打猎用的仿真鸭该怎么办呢?它既不会叫也不会飞,这样又得改写方法了。烦!看来,继承这东西有时也挺烦人的! 噩梦 公司高层决定每半年就要更新该产品,更新的方式他们还没有想好。 Joe的对策 我必须要有一种清晰的方法,让一部分鸭子(而不是全部)能够飞行和鸣叫。 把fly()从Duck中分离出来,设计一个接口Flyable,该接口有一个fly()方法,会飞的鸭子就实现该接口。 对quack()也依此处理。 Joe的解决方案 对Joe新方案的分析 Joe的第二个方案解决了部分问题(不会有会飞的橡皮鸭了),但也完全破坏了代码的重用性(每一种会飞的鸭子都必须实现fly()方法,如果要修改飞行行为,则必须修改每种鸭子的fly()代码,设想有几十种会飞的鸭子)。这从另一个方面增加了维护的难度。 现在让我们将鸭子的行为从Duck类中分离出来! 我们已经知道,fly()和quack()是Duck类中不同的ducks的变化部分。 我们将这些行为从Duck类中分离出来,对于每一个方法,创建一个类的集合来表示相应的行为。例如:对于fly(),我们建立一个类的集合,分别实现翱翔,俯冲,起飞等。 怎么设计实现鸭子飞行和鸣叫行为的类集合? 首先,我们需要灵活性。在此之前,正是由于不灵活给我们带来了麻烦。我们希望能够将行为指定给鸭子的某个实例。例如,我们可能希望生成一个野鸭实例,并以某种飞行行为(例如:翱翔)对它初始化,在这之后,我们就会想能不能动态的改变这只野鸭的行为呢?换句话说,我们应该在Duck类中包含一个设置行为的方法,使得我们能够在运行时改变野鸭的行为(如:由翱翔变为俯冲) 引入接口 对每类行为,我们用一个接口(interface)来表示。例如:用接口FlyBehavior来表示飞行行为,用接口QuackBehavior来表示鸣叫行为。每一个具体的行为类,是这些接口的一个实现(如:翱翔Hover,俯冲Dive,不飞)。 这样做之后,就不是由Duck类来实现飞行和鸣叫接口了,取而代之的是,我们设置了一组类,他们的任务就是表示某个行为,这些行为类将用来实现上面的接口。 现在:鸭子的行为用一个实现特定行为接口的单独的类来表示 新设计方法与以前的方法的差异 这种做法与我们以前的做法不同,以前我们或者是用Duck超类,或者是用Duck的子类本身来具体实现(implements)一个接口。后两种做法都使我们依赖于一个实现,我们被使用这种特定的实现捆住了手脚,要改变鸭子的行为时除了对Duck类或其子类进行修改,增加代码外,别无它法。 新设计方法与以前的方法的差异 在我们新的设计方案中,Du
文档评论(0)