《程序设计模式之策略模式课程设计》由会员分享,可在线阅读,更多相关《程序设计模式之策略模式课程设计(15页珍藏版)》请在金锄头文库上搜索。
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 independently from client
4、s that use it. )策略模式把对象本身和运算规则区分开来,其功能非常强大,因为这个设计模式本身的核心思想就是面向对象编程的多形性的思想。策略模式的功能:把具体的算法实现从具体的业务处理中独立出来来,把它们实现成单独的算法类,从而形成一系列的算法,并让这些算法可以相互替换。策略模式的重心不是如何实现算法,而是如何组织、调用这些算法,从而让程序结构更灵活,具有更好的可维护性和可扩展性策略算法在实现上也是相互独立的,相互之间相互没有依赖的。3. Strategy 模式的结构和使用3.1 策略模式的结构Strategy图:模式的通用结构图策略模式的结构图如上所示:Context 定义了一个
5、面向应用的接口。它维护对一个 Strategy 对象的引用,并使用一个ConcreteStrategy 对象来配置本身。 Strategy 定义所有的的算法的公共接口,Context 使用此接口来调用具体的算法(策略) 。具体算法在 ConcreteStrategy 中实现。这里每一种算法即为一个策略。ClientStrategyAlgorthminterface()ContextContextinterfaceConcreteStrategy CAlgorthminterface()ConcreteStrategy BAlgorthminterface()ConcreteStrategy A
6、Algorthminterface() 当客户调用 Context 时,它将客户的请求转发给它的 Strategy 。Context 将该算法所需的所有数据传递给 Strategy,或者将自身作为参数传递给 Strategy ,使 Strategy 可以回调 Context 。 ConcreteStrategy 实现具体算法。3.2 Strategy 模式以以下几条原则为基础:(1)对象都具有职责,这些职责不同的具体实现是通过多态的使用完成的。(2)概念上相同的算法具有多个不同的实现,需要进行管理。将问题域中的各个行为互相分离开来-也就是说将他们解耦,是一个好的设计实践,这使得我们可以修改负责
7、某一行为的类,不会对其它的类产生不良影响3.3 Strategy 模式关键特征A.意图:可以根据所处的上下文,使用不同的的业务规则或算法;问题:对所需算法的选择取决于发出请求的客户或者要处理的数据,如果只有一些不会变化的算法,就不需要 Strategy 模式;B.解决方案:将对算法的选择和算法的实现相分离。允许根据上下文进行选择;C.参与者与写作者:Strategy 模式制定了如何使用不同的算法,各 ConcreteStrategy 实现了这些不同个算法, Context 通过类型Strategy 的引用时用具体的 ConcreteStrategy,Strategy 与 Contextx 相互
8、作用以实现所选的算法,Context 将均来自 Context 的请求转发给Strategy。D.效果:Strategy 模式定义了一些列的算法;可以不使用Switch 语句或条件语句;必须以相同的方法调用所有的算法, (他们之间必须拥有相同的接口) ,各 ConcreteStrategy 与 Context 中加入获取状态的方法.E.实现:让使用算法的类(Context)包含一个抽象类(Strategy) ,该抽象类由一个抽象方法制定如何让调用算法,每个派生类按需要实现算法。注意:在原型 Strategy 模式中,选择所有具体实现的职责由Context 对象承担,并转给 Strategy 模
9、式的 Context 对象3.4 Strategy 模式的组成环境类(Context):用一个 ConcreteStrategy 对象来配置。维护一个对 Strategy 对象的引用。可定义一个接口来让 Strategy 访问它的数据。抽象策略类(Strategy):定义所有支持的算法的公共接口。Context 使用这个接口来调用某 ConcreteStrategy 定义的算法。具体策略类 (ConcreteStrategy ):Strategy 接口实现某具体算法。4. Strategy 模式的优点1) 相关算法系列 Strategy 类层次为 Context 定义了一系列的可供重用的算法或
10、行为。 继承有助于析取出这些算法中的公共功能。2) 提供了可以替换继承关系的办法: 继承提供了另一种支持多种算法或行为的方法。你可以直接生成一个 Context 类的子类,从而给它以不同的行为。但这会将行为硬行编制到 Context 中,而将算法的实现与 Context 的实现混合起来,从而使 Context 难以理解、难以维护和难以扩展,而且还不能动态地改变算法。最后你得到一堆相关的类 , 它们之间的唯一差别是它们所使用的算法或行为。 将算法封装在独立的 Strategy 类中使得你可以独立于其 Context 改变它,使它易于切换、易于理解、易于扩展。3) 消除了一些 if else 条件
11、语句 :Strategy 模式提供了用条件语句选择所需的行为以外的另一种选择。当不同的行为堆砌在一个类中时 ,很难避免使用条件语句来选择合适的行为。将行为封装在一个个独立的 Strategy 类中消除了这些条件语句。含有许多条件语句的代码通常意味着需要使用 Strategy 模式。4) 实现的选择 Strategy 模式可以提供相同行为的不同实现。客户可以根据不同时间 /空间权衡取舍要求从不同策略中进行选择。5. 适合使用策略模式的情景在下述情况下可以使用策略模式。(1)许多相关的类仅仅是行为有异。 “策略”提供了一种用多个行为中的一个行为来配置一个类的方法。(2)需要使用一个算法的不同变体。
12、当这些变体实现为一个算法的类层次时,可以使用策略模式。(3)算法使用客户不应该知道的数据。可使用策略模式以避免暴露复杂的,与算法相关的数据结构。(4)一个类定义了多种行为,并且这些行为在这个类的操作中以多个条件语句的形式出现。将相关的条件分支一如它们各自的 Strategy类中以代替这些条件语句。6. Strategy 模式在 Java 中的应用在我们的日常生活中,经常遇到这样的事情:同一件事情在不同的情况下或针对不同的对象会有不同的做法。用程序设计术语来说就是:同样的接口,在不同的情况下需要使用不同的算法。而我们现在所要说的策略模式就是能够实现这一功能的一种设计模式,它可以在不影响客户端的情
13、况下进行多个算法的替换。例如,我们在一家餐厅吃饭,针对套餐,不同年龄的人可能收费不一样,大人如父母 40 元每份,老人 20 元每份,小孩子 10 元每份。如果要设计个软件来做这件事,那么通常首先考虑的是使用ifelse 或 switch 之类的结构来解决这个问题,例如如下代码:(代码不能运行,仅仅说明问题)java view plaincopyprint?1. public class Client 2. 3. public static void main(String arg) 4. showPrice(persontypeType); 5. 6. 7. 8. public static
14、 void showPrice(persontype persontypeType) 9. if(persontypeType.equals(daren)/大人 10. System.out.println(每份 40); 11. else 12. if(persontypeType.equals(laoren)/老人13. System.out.println(每份 20); 14. else 15. if(persontypeType.equals(xiaihai)/小孩子System.out.println(每份 10); 16. 17. 18. 19. 仔细分析一下就会知道,这个程序的
15、可变性代码就是 3 个算法,因此可以先把这 3 个算法分别用 3 个类封装起来。由于算法就放在客户端,所以一旦某个计算方法发生变化,显然它违背了开- 闭原则,没有把可变性代码进行封装,所以这不是个好程序。ChargeType 是抽象类,客户面对的是抽象角色,而真正算法的实现是抽象角色的子类。也就是说,可变的算法已经与客户实现了隔离,从而提高了程序的可维护性。程序源代码:(异常简单,仅仅说明问题)java view plaincopyprint?1. public abstract class ChargeType 2. public abstract void chargeInfo(); 3. 4. 5. 6. 7. public class darenCharge extends ChargeType 8. 9. Override 10. public void chargeInfo() 11. System.out.println(每份 40 元);/ 算法代码 12. 13. 14.