程序设计模式之策略模式课程设计汇总_第1页
程序设计模式之策略模式课程设计汇总_第2页
程序设计模式之策略模式课程设计汇总_第3页
程序设计模式之策略模式课程设计汇总_第4页
程序设计模式之策略模式课程设计汇总_第5页
已阅读5页,还剩13页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、河南理工大学程序设计模式结课论文2012 20013 学年 第 2 学期论文题目 策略模式学生姓名学号专业班级指导教师题目1. Strategy 模式概述摘要:设计模式是一种高级软件重用技术, 即在软件开发过程中, 在特定环境下解决问题的方法。 使用设计模式可以更加简便的重用成 功的设计和已有的体系结构。本文以一个简单的例子介绍了策略模 式,并给出了策略模式的 java 实现。在生活中,我们经常需要就执行某项任务或解决某个问题的一 般方法做出抉择, 这种情况在软件开发中也屡见不鲜, 我们大多数人 都已经了解到,短期的抄近路,可能会在长期导致问题严重复杂化,在软件开发中也常常遇到类似的情况,实现

2、某一个功能有多种 算法或者策略,我们可以根据环境或者条件的不同选择不同的算法或 者策略来完成该功能。如查找、排序等,一种常用的方法是硬编码 (Hard Coding) 在一个类中,如需要提供多种查找算法,可以将这些 算法写到一个类中, 在该类中提供多个方法, 每一个方法对应一个具 体的查找算法;当然也可以将这些查找算法封装在一个统一的方法 中,通过 ifelse 或者 case 等条件判断语句来进行选择。这两种 实现方法我们都可以称之为硬编码,如果需要增加一种新的查找算 法,需要修改封装算法类的源代码;更换查找算法,也需要修改客户 端调用代码。 在这个算法类中封装了大量查找算法, 该类代码将较

3、复 杂,维护较为困难。如果我们将这些策略包含在客户端,这种做法更不可取,将导致客户端程序庞大而且难以维护, 如果存在大量可供选 择的算法时问题将变得更加严重。2. Strategy 模式的定义策略模式是一种行为模式。定义一系列的算法,把他们一个个 封装起来,并且使他们可以相互替换,并对用户提供统一的接口,策 略模式使算法可独立于使用它的客户而变化。 ( Define a family of algorithms,encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary indepe

4、ndently from clients that use it. )策略模式把对象本身和运算规则区分开来,其功能非常强大, 因为这个设计模式本身的核心思想就是面向对象编程的多形性的思 想。策略模式的功能:把具体的算法实现从具体的业务处理中独立出 来来,把它们实现成单独的算法类,从而形成一系列的算法,并让这 些算法可以相互替换。策略模式的重心不是如何实现算法, 而是如何组织、 调用这些算 法,从而让程序结构更灵活, 具有更好的可维护性和可扩展性策略算 法在实现上也是相互独立的,相互之间相互没有依赖的。3. Strategy 模式的结构和使用3.1 策略模式的结构Context Strategy

5、Contextinterfa ceStrategyAlgorthminter face()ConcreteStrateAlgorthminter face()ConcreteStrate gy B Algorthminter face()ConcreteStrate gy C Algorthminter face()图:模式的通用结构图策略模式的结构图如上所示: Context定义了一个面向应用的接口它维护对一个 Strategy 对象的引用,并使用一个 ConcreteStrategy 对 象来配置本身。 Strategy 定义所有的的算法的公共接口, Context 使用 此接口来调用具体

6、的算法 (策略)。具体算法在 ConcreteStrategy中实现。这里每一种算法即为一个策略。当客户调用 Context 时,它将客户的请求转发给它的 StrategyContext 将该算法所需的所有数据传递给 Strategy,或者将自身作为参 数传 递 给 Strategy , 使 Strategy 可以回 调 Context 。 ConcreteStrategy实现具体算法。3.2 Strategy 模式以以下几条原则为基础:(1)对象都具有职责,这些职责不同的具体实现是通过多态的使用 完成的。(2)概念上相同的算法具有多个不同的实现,需要进行管理。 将问题域中的各个行为互相分离开

7、来 也就是说将他们解耦,是一个好的设计实践,这使得我们可以修改负责某一行为的类, 不会对其它的类产生不良影响3.3 Strategy 模式关键特征A. 意图:可以根据所处的上下文, 使用不同的的业务规则或算法; 问题:对所需算法的选择取决于发出请求的客户或者要处理的数 据,如果只有一些不会变化的算法,就不需要 Strategy 模式;B. 解决方案: 将对算法的选择和算法的实现相分离。 允许根据上 下文进行选择;C. 参与者与写作者: Strategy 模式制定了如何使用不同的算法, 各 ConcreteStrategy 实现了这些不同个算法, Context 通过类型 Strategy 的引

8、用时用具体的 ConcreteStrategy,Strategy 与 Contextx 相 互作用以实现所选的算法, Context 将均来自 Context 的请求转发给Strategy。D. 效果: Strategy 模式定义了一些列的算法;可以不使用 Switch 语句或条件语句 ;必须以相同的方法调用所有的算法, (他们之间必须 拥有相同的接口),各 ConcreteStrategy与 Context 中加入获取状态的 方法.E. 实现:让使用算法的类 ( Context)包含一个抽象类 (Strategy), 该抽象类由一个抽象方法制定如何让调用算法, 每个派生类按需要实 现算法。注

9、意:在原型 Strategy 模式中,选择所有具体实现的职责由 Context对象承担,并转给 Strategy模式的 Context 对象3.4 Strategy 模式的组成环境类( Context ) :用一个 ConcreteStrategy 对象来配置。维 护一个对 Strategy 对象的引用。可定义一个接口来让 Strategy 访问 它的数据。抽象策略类( Strategy ):定义所有支持的算法的公共接口。 Context 使用这个接口来调用某 ConcreteStrategy 定义的算法。具体策略类 (ConcreteStrategy ):Strategy 接口实现某具体 算

10、法。4. Strategy 模式的优点1) 相关算法系列 Strategy 类层次为 Context 定义了一系列的可供重 用的算法或行为。 继承有助于析取出这些算法中的公共功能。2)提供了可以替换继承关系的办法: 继承提供了另一种支持多种算 法或行为的方法。 你可以直接生成一个 Context 类的子类, 从而给它 以不同的行为。但这会将行为硬行编制到 Context 中,而将算法的 实现与 Context 的实现混合起来 ,从而使 Context 难以理解、难以维 护和难以扩展, 而且还不能动态地改变算法。 最后你得到一堆相关的 类 , 它们之间的唯一差别是它们所使用的算法或行为。 将算法

11、封装 在独立的 Strategy 类中使得你可以独立于其 Context 改变它,使它易 于切换、易于理解、易于扩展。3)消除了一些 if else 条件语句 :Strategy 模式提供了用条件语句选 择所需的行为以外的另一种选择。当不同的行为堆砌在一个类中时 很难避免使用条件语句来选择合适的行为。 将行为封装在一个个独立 的 Strategy 类中消除了这些条件语句。含有许多条件语句的代码通 常意味着需要使用 Strategy 模式。4)实现的选择 Strategy 模式可以提供相同行为的不同实现。 客户可 以根据不同时间 /空间权衡取舍要求从不同策略中进行选择。5. 适合使用策略模式的情

12、景在下述情况下可以使用策略模式。 (1)许多相关的类仅仅是行为有异。 “策略”提供了一种用多个行为 中的一个行为来配置一个类的方法。(2)需要使用一个算法的不同变体。当这些变体实现为一个算法的 类层次时,可以使用策略模式。(3)算法使用客户不应该知道的数据。可使用策略模式以避免暴露 复杂的,与算法相关的数据结构。(4)一个类定义了多种行为,并且这些行为在这个类的操作中以多 个条件语句的形式出现。将相关的条件分支一如它们各自的 Strategy 类中以代替这些条件语句。6. Strategy 模式在 Java 中的应用在我们的日常生活中,经常遇到这样的事情:同一件事情在不 同的情况下或针对不同的

13、对象会有不同的做法。 用程序设计术语来说 就是:同样的接口,在不同的情况下需要使用不同的算法。而我们现 在所要说的策略模式就是能够实现这一功能的一种设计模式, 它可以 在不影响客户端的情况下进行多个算法的替换。例如,我们在一家餐厅吃饭,针对套餐,不同年龄的人可能收 费不一样,大人如父母 40元每份,老人 20 元每份,小孩子 10元每 份。如果要设计个软件来做这件事,那么通常首先考虑的是使用 if else 或 switch 之类的结构来解决这个问题,例如如下代码: (代码不 能运行,仅仅说明问题)java view plaincopyprint?1. public class Client

14、2.3.public static void main(String arg)4.showPrice(persontypeType);.public static void showPrice(persontype persontypeType)9.if (persontypeType.equals(daren)/ 大人10.System.out.println( 每份 40 );11.else12.if (persontypeType.equals(laoren)/ 老人13.System.out.println( 每份 20 );14.else15.if (persontyp

15、eType.equals(xiaihai)/ 小孩子System.out.println( 每份 10 );9.仔细分析一下就会知道, 这个程序的可变性代码就是 3 个算法,因此 可以先把这 3 个算法分别用 3 个类封装起来。由于算法就放在客户端, 所以一旦某个计算方法发生变化, 显然它违背了 开-闭 原则,没有把 可变性代码进行封装,所以这不是个好程序。ChargeType是抽象类,客户面对的是抽象角色,而真正算法的实 现是抽象角色的子类。 也就是说,可变的算法已经与客户实现了隔离, 从而提高了程序的可维护性。程序源代码:(异常简单,仅仅说明问题)java view p

16、laincopyprint?1. public abstract class ChargeType 2. public abstract void chargeInfo();6345 public class darenCharge extends ChargeTypeOverridepublic void chargeInfo() System.out.println(public class laorenChargeOverridepublic void chargeInfo() System.out.println(public class xiaohaiChargeOverride p

17、ublic void chargeInfo() System.out.println(7.综合应用举例每份 40 元); / 算法代码extends ChargeType 每份 20 元 );extends ChargeType 每份 10 元 );0.在新的案例研究中, 我们来考虑一个美国某国际电子商务公司的 订单处理系统, 这个系统必须能够处理许多不同个国家的订单, 这个 系统构架中有一个控制器对象

18、, 用于处理销售请求, 它能够确认何时 有人请求销售订单, 并将该请求转发给 Salesorder对象进行订单处理,订单体系结构系统大致如图:TaskControllerSalesOrder其中: SalesOrder对象的功能包括:允许客户通过 GUI 填写订单:处理税额的计算; 处理订单,打印销售收据;有些功能可能需要借助其他对象实现,比如, SalesOrder 对象 没有必要自己打印,它的作用是充当一个存放销售订单信息的容器, 具体的 SalesOrder对象可以调用 SalesTicket对象来打印。根据这种方法,应该这样做:寻找变化,并将它封装在一个单独 的类中;将这个类包含在另一

19、个类中;在本例中,已经确定缴税规则是变化的, “将它封装”就意味着 创建一个抽象类定义如何在概念上完成税额计算, 然后每种变化派生 具体的类,也就是说可以创建一个 CalcTax 对象,为完成税额计算这一任务定义接口,然后由他派生所需的特定版本CalcTax+taxAmount(in itemSold:Salable,in qty:double, in price :double):doubleCanTaxUSTax接下来,应该使用组合取代继承, 这意味着用不着在创建不同版 本的销售订单,(使用继承),可以用组合来包含变化,也就是说,只 有一个 SalasOrder类,让它包含处理变化的 Ca

20、lcTax 类,如图TskControllerSalesOrdeer +calcTax()CalcTax+taxAmount(in itemSold:Salable,in qty:double, in price :double):doubleCanTaxUSTaxJava 代码片段:实现 Strategy 模式 模式Public class TaskController Public void process() /这里的代码模拟了处理任务控制器/、/取得所在国的信息CalcTax myTax;myTax = getTaxRulesForCountry();SalasOrder mySO =

21、 new SalesOrder(); mySO.process (myTax);Private CalcTax getTaxRulesForCountry() /在实际开发中,要去的所在国的计税规则 /相应逻辑可以写在这里,也可以放到配置文件中 /这里返回 USTax 就可以编译了Return new USTax();Public calss SalesOrder Public void process (CalcTax taxToUse)Long itemNumber = 0;Double price = 0;/创建计税对象 /、/计算税额Double tax = taxToUse.taxAmount( itemNumber,price);Public abstract calss CalcTaxAbstract public double taxAmount(Long itemSold,double price);Public calss C

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论