面向对象的设计模式.ppt_第1页
面向对象的设计模式.ppt_第2页
面向对象的设计模式.ppt_第3页
面向对象的设计模式.ppt_第4页
面向对象的设计模式.ppt_第5页
已阅读5页,还剩106页未读 继续免费阅读

下载本文档

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

文档简介

面向对象的设计模式Object OrientedDesignPatterns 2 内容安排 从原则到模式设计模式GoF设计模式模式与编程语言 3 模式 如何在已排序的值列表中查找一个数组 1 将列表一分为二 将要查找的值与中间元素的值相比较 如果相等 就找到我们要查找的值 如过要查找的值小于中间元素的值 将中间点设置为列表的新的顶点 并再次将列表一分为二 如果要查找的值大于中间元素的值 将中间点设置为列表的新的尾点 然后再将列表一分为二 继续这种分割过程 直到列表不能再分为止 此时 如果要查找的值不再最后两个元素中 它就不在这个列表中 2 使用二分查找 4 设计 Maslov 如果你唯一的工具是锤子 你就会把所有的东西都当作钉子 1 绝大多数开发人员和设计人员都是程序员出身 他们习惯于最熟悉的工具 即编写代码的文本编辑器 来思考 2 设计主要是一个交流的活动 而程序员的交流能力通常非常糟糕 BuildforToday DesignforTomorrow 5 设计模式 6 模式 PatternAdecorativedesign asforwallpaper madeupofelementsinaregulararrangementArecognizablecombinationofaction qualities etc characteristicofaparticularpersonorpopulation通用问题的解决方案来自建筑行业ChristopherAlexander1977年 APatternLanguage 7 模式的形式 模式的一个主要目标就是以一种别人容易接受的方式 捕捉那些重复出现的问题的解决方案模式的形式 名称意图动机适用性结构参与者协作效果实现 8 模式简史 1 1964ChristopherAlexander出版了NotesontheSynthesisofForm 该书尝试从一个不同的角度来看待建筑的过程1977ChristopherAlexander出版了APatternLanguage一书1987WardCunningham和KentBeck开始将一些建筑学概念应用到使用SmallTalk语言的软件开发中1992JimCoplien出版了AdvancedC ProgrammingStyleandIdioms一书1992PeterCoad在ACM上发表了他在分析模式方面的研究成果1993ErichGamma的博士论文以及JohnVlissides RalphJohnson和RichardHelm的其它研究成果在ECOOP93上发表1993KentBeck GradyBooch JimCoplien以及其他人组成了Hillside小组 提供一个讨论模式的论坛 9 模式简史 2 1994第一次编程模式语言 PatternLanguageofProgramming PLoP 大会举行1994DesignPatterns ElementsofReusableObject OrientedSoftware出版1996FrankBuschmann与其他人合作出版了Pattern OrientedSoftwareArchitecture ASystemofPatterns一书1997MartinFlower出版了AnalysisPatterns ReusableObjectModels一书1999MartinFlower与其他人合作出版了Refactoring ImprovingtheDesignofExistingCode一处 10 设计模式 什么是设计模式 设计就是解决方案 对某个问题的解决如果某个解决方案对某类问题都很有用这时就把它总结出来这就产生了设计模式 11 设计模式 是 优秀的设计范例从优秀设计方案中发现和总结出来的经验在实践中反复出现的设计问题的优秀解决方案设计者相互交流的基本术语 设计语言培养优秀设计师的一条捷径不是 面向对象设计的框架可供简单组合的设计元件发明创造出来的创新思路解决面向对象设计问题的完整方案 12 设计模式的基本要素 1 名称 用于助记 形象表示这个模式2 问题 这个模式可以解决什么问题3 解决方案 这个模式怎样解决这个问题的步骤与方法4 效果 使用这个模式与不使用这个模式有什么区别 它有什么优点和缺点 一个问题可以有多种解法 好的解法都可以找到很多种 每种都有优缺点 所以编程时不要死记方法 应该活学活用 13 设计模式的基本思想 1 软件是在不断进化的需求在不断改变 所以软件应该适应变化设计模式是为了让软件更加适应变化 有更多的可复用性 就是有变化时你不用从头重写一次这个软件如何适应变化 就应该封装变化 让变化的影响最小封装复杂性 提供简单的接口 14 设计模式的基本思想 2 1 松耦合2 针对接口编程 而不是针对实现编程3 继承 组合 委托 多态 参数化 15 GoF模式分类 根据模式的目的 用来完成什么工作的 创建型模式结构型模式行为型模式根据模式的作用范围 是处理类还是处理对象的 类模式对象模式 16 GoF设计模式 GoF23种经典设计模式 17 本章讲解的设计模式 Singleton模式Factory模式简单工厂工厂方法抽象工厂State模式Adapter模式Observer模式Facade模式 18 单态模式 singleton 一个单态类只可有一个实例 这样的类常用来进行资源管理 例如 很多软件都有数据库 一般而言 整个软件应当使用一个联接通道 而不是任意在需要时就新打开一个联接通道 19 单态类的特性 1 单态类只可有一个实例 2 它必须自己创立自己这唯一的一个实例 3 它必须给所有其它的类提供自己这一实例 最后 单态类在理论和实践上都并非限定只能有 一个 实例 而是很容易推广到任意有限个实例的情况 单态模式的几种实现 饿汉式单态类 20 饿汉式单态类 由于构造器是私有的 因此此类不能被继承packagecom javapatterns singleton demos publicclassEagerSingleton privateEagerSingleton publicstaticEagerSingletongetInstance returnm instance privatestaticfinalEagerSingletonm instance newEagerSingleton 21 懒汉式单态类 懒汉式单态类在第一次被引用时将自己实例化 22 懒汉式单态类 构造子是私有的 因此此类不能被继承publicclassLazySingleton privateLazySingleton synchronizedpublicstaticLazySingletongetInstance if m instance null m instance newLazySingleton returnm instance privatestaticLazySingletonm instance null 23 两种单态类的比较 饿汉式单态类在自己被加载时就将自己实例化 单从资源利用效率角度来讲 这是比懒汉式单态类稍差些 从速度和反应时间角度来讲 则比懒汉式单态类稍好些 懒汉式单态类在实例化时必须处理好在多个线程 同时首次引用此类时 实例化函数内部关键段的访问限制问题 24 25 举例 使用一个Calendar回答 二月有多少天 等问题 而不是创建多个Calendar对象 Calendarcalendar Calendar getInstance 26 工厂模式 Factory 工厂模式就是专门负责将大量有共同接口的类实例化 而且不必事先知道每次是要实例化哪一个类的模式 工厂模式有以下几种形态 简单工厂 SimpleFactory 模式工厂方法 FactoryMethod 模式抽象工厂 AbstractFactory 模式 27 简单工厂 SimpleFactory 模式 比如说 你有一个描述你的后花园的系统 在你的后花园里有各种的花 但还没有水果 你现在要往你的系统里引进一些新的类 用来描述下列的水果 葡萄Grapes草莓Strawberry苹果Apple 28 简单工厂 SimpleFactory 模式 29 简单工厂 SimpleFactory 模式 作为小花果园的主人兼园丁 也是系统的一部分 自然要由一个合适的类来代表 这个类就是FruitGardener类 30 园丁的工作 简单工厂 FruitGardener类会根据要求 创立出不同的水果类 比如苹果Apple 葡萄Grape或草莓Strawberry的实例 这里的园丁就如同一个可以创建水果产品的工厂一样如果接到不合法的要求 FruitGardener类会给出例外BadFruitException 31 丰收的果园 客户端 在使用时 只须呼叫FruitGardener的factory 方法即可try FruitGardenergardener newFruitGardener FruitIFgrape gardener factory grape FruitIFapple gardener factory apple FruitIFstrawberry gardener factory strawberry catch BadFruitExceptione 32 小结 简单工厂模式的定义 总而言之 简单工厂模式就是由一个工厂类根据参数来决定创立出哪一种产品类的实例 把实例化的责任与使用实例的责任分割开来 33 工厂方法模式 在简单工厂模式中 一个工厂类处于对产品类实例化调用的中心位置上 它决定那一个产品类应当被实例化 工厂方法模式是简单工厂模式的进一步抽象化和推广 它比简单工厂模式聪明的地方在于 它不再作为一个具体的交通警察的面貌出现 而是以交通警察局 工厂 的面貌出现 具体的警察成为工厂方法的执行者 工厂方法模式里不再只由一个工厂类决定哪一个产品类应当被实例化 这个决定被交给子类去作 34 开始种植蔬菜 我们准备再次引进蔬菜类植物 比如 西红柿 Tomato 土豆 Potato 西芥兰花 Broccoli 蔬菜需要喷洒 dust 杀虫剂 pesticide 除虫 35 为什么需要工厂方法模式 简单工厂模式 FruitGardener掌握所有水果类的生杀大权 36 为什么需要工厂方法模式 再设计一个专管蔬菜类植物的工厂类 这样做一个明显的不足点就是不够一般化和抽象化 在FruitGardener和VeggieGardener类之间明显存在很多共同点 这些共同点应当抽出来一般化和框架化 这样一来 如果后花园的主人决定再在园子里引进些树木类植物时 我们有框架化的处理方法 37 工厂方法模式的定义 38 工厂方法模式的定义 ConcreteCreator的factory 方法返还的数据类型是一个接口PlantIF 而不是哪一个具体的产品类 这种设计使得工厂类创立哪一个产品类的实例细节完全封装在工厂类内部 工厂方法模式又叫多形性工厂模式 是因为实工厂类都有共同的接口 或者都有共同的抽象父类 39 工厂方法模式在小花果园系统中的实现 40 工厂方法模式在小花果园系统中的实现 取代了过去的全能角色的是一个抽象的园丁这个角色规定出具体园丁角色需要实现的具体职能 而真正负责作物管理的则是各种作物的具体园丁角色 41 工厂方法模式在小花果园系统中的实现 42 抽象工厂模式 抽象工厂模式是所有形态的工厂模式中最为抽象和最具广泛性的一种形态 抽象工厂模式是工厂方法模式的进一步扩广化和抽象化 43 抽象工厂模式 44 抽象工厂模式 在抽象工厂模式中 抽象产品 AbstractProduct 可能是一个或多个 从而构成一个或多个产品族 ProductFamily 在只有一个产品族的情况下 抽象工厂模式实际上退化到工厂方法模式 45 抽象工厂模式 46 抽象工厂模式在小花果园系统中的实现 47 抽象工厂模式在小花果园系统中的实现 48 抽象工厂模式在小花果园系统中的实现 两处花园就相当于两个产品族 显然 给北方花园的植物是要种植在一起的 给南方花园的植物是要另种植在一起的 这种分别应当体现在系统的设计上面 49 抽象工厂 AbstractFactory 类或接口 担任这个角色的是模式的核心 它是与应用程序无关的 任何在模式中创立对象的工厂类必须实现这个接口 或继承这个类 实工厂类 ConreteFactory 担任这个角色的是与应用程序紧密相关的 直接在应用程序调用下 创建产品实例或者使用工厂方法创建产品实例的那样一些类 50 抽象产品 AbstractProduct 担任这个角色的类是工厂方法模式所创立的对象的父类 或它们共同拥有的接口 实产品 ConcreteProduct 担任这个角色的类是工厂方法模式所创立的任何对象所属的类 接口Gardener packagecom javapatterns abstractfactory publicinterfaceGardener 51 实工厂类NorthenGardener packagecom javapatterns abstractfactory publicclassNorthenGardenerimplementsGardener publicVeggieIFcreateVeggie Stringname returnnewNorthernVeggie name publicFruitIFcreateFruit Stringname returnnewNorthernFruit name 52 实工厂类TropicalGardener packagecom javapatterns abstractfactory publicclassTropicalGardenerimplementsGardener publicVeggieIFcreateVeggie Stringname returnnewTropicalVeggie name publicFruitIFcreateFruit Stringname returnnewTopicalFruit name 53 接口VeggieIF packagecom javapatterns abstractfactory publicinterfaceVeggieIF 54 实产品类NorthernVeggie 实产品类NorthernFruit与此极为类似 故略去 packagecom javapatterns abstractfactory publicclassNorthernVeggieimplementsVeggieIF publicNorthernVeggie Stringname this name name publicStringgetName returnname publicvoidsetName Stringname this name name privateStringname 55 实产品类TropicalVeggie 实产品类TropicalFruit与此极为类似 故略去 packagecom javapatterns abstractfactory publicclassTropicalVeggieimplementsVeggieIF publicTropicalVeggie Stringname this name name publicStringgetName returnname publicvoidsetName Stringname this name name privateStringname 56 57 State模式 修改LegoSystem源代码caseBLUE BlueProcess break LegoSystem ProcessColor switch color caseRED RedProcess break caseGREEN GreenProcess break caseYELLOW YellowProcess break 58 State模式 目的 允许一个对象在其内部状态改变时改变其行为结构适用性 一个对象的行为取决于它的状态 并且它必须在运行时刻根据状态改变它的行为一个操作中含有庞大的多分支的条件语句 且这些分支依赖于该对象的状态 这个状态通常用一个或多个枚举常量表示State模式将每一个条件分支放入一个独立的类中 这使得可以根据对象自身的情况将对象的状态作为一个对象 这一对象可以不依赖于其他对象而独立变化 59 State模式 60 State模式 LegoSystem ProcessColor Color Process CColor public virtualvoidProcess voidCRed Process RedProcess voidCGreen Process RedProcess voidCYellow Process RedProcess 仅需要增加新的类 原有代码不需要任何变动voidCBlue Process BlueProcess State模式满足OCP 61 可复用的Button Buttonkey9 newButton 9 ButtonkeyDial dialKeySingleton ButtonkeyPower powerKeySingleton 62 拨电话 的协作图 63 观察静态结构 类图 64 根据类图试写Button代码 publicclassButton privateDialermyDialer publicButton Dialerdialer myDialer dialer publicbuttonPressed Stringtoken throwsNumberFormatException intdigit Integer parseInt token dialer digit digit Button与Dialer之间出现耦合 从而破坏了Button的可复用性我们考虑增加一个间接层来解决 65 添加一个间接层 添加一个怎样的类 两个关系是怎样的 X 66 改进设计 面向对象设计对付类耦合的基本对策是 将两个类之间的关联转变为一个类与一个接口之间的关联 或者两个接口之间的关联 67 新的问题 interfaceButtonListener publicvoidbuttonPressed inttoken publicclassDialerimplementsButtonListener publicvoidbuttonPressed inttoken 问题在于 Dialer为什么一定要能够处理buttonPressed事件 为什么一定要求Dialer能够接受int型的数值作为输入 如果Dialer是已经做好的配件 只能接受一个字符串表示的电话号码 又该怎么办 这种设计限制了Dialer的可复用性 68 再增加一个间接层 69 Adapter模式 目的 将一个类的接口转换成客户希望的另外一个接口 Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作适用性 使用一个已经存在的类 而它的接口不符合需求创建一个可以复用的类 该类可以与其它不相关的类或不可预见的类 即那些接口不一定兼容的类 协同工作使用一些已经存在的子类 但是不可能对每一个都进行子类化以匹配它们的接口 对象Adpater可以适配它的父类接口 70 Adapter模式 结构 71 代码实现 interfaceButtonListener voidbuttonPressed intdigit publicclassDialer publicvoiddial Stringpno radio connect pno publicclassButtonDialerAdapterimplementsButtonListener StringBuffermyPho DialermyDialer voidbuttonPressed intdigit if digit DIAL SIGNAL myDialer dial myPho elsemyPho append digit 72 引发潜在问题 既然Dialer只在拨号时反应 那么按下数字键时 如何让Speaker发音 73 如法炮制 现在的关键问题是 Button必须可以在被按下的时候 通知数量未知的监听者 或者说 观察者 observer 74 Observer模式 目的 定义对象间的一种一对多的依赖关系 当一个对象的状态发生改变时 所有依赖于它的对象都得到通知并被自动更新适用性 当一个抽象模型有两个方面 其中一个方面依赖于另一方面 将这二者封装在独立的对象中以使它们可以各自独立地改变和复用当对一个对象的改变需要同时改变其它对象 而不知道具体有多少对象有待改变当一个对象必须通知其它对象 而它又不能假定其它对象是谁 换言之 你不希望这些对象是紧密耦合的 75 Observer模式 结构 76 实现Observer publicclassButton privateintmyDigit INVALID DIGIT privateLinkedListobservers null booleanaddObserver ButtonListenerbl returnobservers add bl voidpressed ListIteratorli observers listIterator while li hasNext ButtonListenerbl ButtonListener li next bl buttonPressed myDigit 忽略了对类型不匹配的检查 77 观察者模式类图 78 抽象主题 Subject 角色 主题角色把所有的观察者对象的引用保存在一个列表里 每个主题都可以有任何数量的观察者 主题提供一个接口可以加上或撤销观察者对象 主题角色又叫做抽象被观察者 Observable 角色 79 具体主题 ConcreteSubject 角色 保存对具体观察者对象有用的内部状态 在这种内部状态改变时给其观察者发出一个通知 具体主题角色又叫作具体被观察者角色 80 具体观察者 ConcreteObserver 角色 保存一个指向具体主题对象的引用 具体观察者角色实现抽象观察者角色所要求的更新自己的接口 以便使本身的状态与主题的状态自恰 81 观察者模式在Java中 从AWT1 1开始视窗系统的事件模型采用观察者模式 因此观察者模式在Java语言里的地位较为重要 在Java语言的java util库里面 提供了一个Observable类以及一个Observer接口 构成Java语言对观察者模式的支持 82 Java观察者模式类图 83 Observable类 被观察者类都是java util Observable类的子类 84 Observer接口 packagejava util publicinterfaceObserver 当被观察的对象发生变化时 这个方法会被调用 voidupdate Observableo Objectarg 85 门面模式 Facade 门面模式是结构模式外部与一个子系统的通信必须通过一个统一的门面 Facade 对象进行 这就是门面模式门面模式可以减低对子系统接口的依赖 86 子系统的客户端 使用一个子系统的客户端往往只关注一些特定的功能 需要同时与子系统内部的许多对象打交道后才能达到目的 87 医院的例子 88 医院的解决方案 89 什么是门面模式 门面模式要求一个子系统的外部与其内部的通信必须通过一个统一的门面对象进行 门面模式通过一个高层次的接口 使的子系统更易于使用 90 示意图 子系统并不知道门面的存在 对于子系统而言 门面仅仅是另外一个客户端而已 91 门面模式的实现 如果一个系统有好几个子系统 每一个子系统都可以有一个门面类 整个系统可以有数个门面类 92 举例 一个保安系统由两个录像机 三个电灯 一个遥感器和一个警报器组成 操作人员要经常启动和关闭这些仪器 93 不使用门面模式的设计 94 举例 使用门面模式的设计 门面模式作用 使用门面模式我们可以 为一个复杂的系统提供一个简单的接口保持子系统的独立性构建层次化系统 使用Facade定义每一层的入口 95 责任链模式 从击鼓传花谈起 击鼓者将花传给贾母 开始传花游戏 花由贾母传给贾赦 由贾赦传给贾政 由贾政传给贾宝玉 又由贾宝玉传给贾环 由贾环传回给贾母 如此往复 见下图 当鼓声停止时 手中有花的人就得执行酒令 96 责任链模式 ChainofResponsibility 很多的对象由每一个对象对其下家的引用而联接起来形成一条链 请求在这个链上传递 直到链上的某一个对象决定处理此请求 发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求责任链可能是一条直线 一个环链甚至一个树结构的一部分 97 责任链模式 目的 使多个对象都有机会处理请求 从而避免请求的发送者和接受者之间的耦合关系 适用性 有多个对象可以处理一个请求 哪个对象处理该请求运行时自动确定在不明确指定接受者的情况下 向多个对象中的一个提交一个请求可处理一个请求的对象集合应被动态指定 98 抽象处理者 Handler 角色 定义出一个处理请求的接口 如果需要 接口可以定义出一个方法 以返回对下家的引用 99 具体处理者 ConcreteHandler 角色 接到请求后 可以选择将请求处理掉 或者将请求传给下家 100 击鼓传花系统的类图 101 责任链模式的静态类结构 102 纯的责任链模式 一个纯的责任链模式要求一个具体的处理者对象只能在两个行为中选择一个 一是承担责任二是把责任推给下家纯的责任链模式的实际例子很难找到某一个具体处理者对象在承担了一部分责任后又把责任向下传 一个请求可以最终不被任何接受端对象所接受 103 举例 AWT事件浮升机制 事件首先传播到它所发生的部件上 然后向其父类处理器传播 容器可以选择处理这个事件 或者再将此事件向更高一级的父类处理器传播 事件如此一级级地向上传播 就像水底的气泡一点一点地冒到水面上一样 因此又叫做事件浮升机制 104 举例 AWT库里处理事件的代码 publicbooleanaction Eve

温馨提示

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

评论

0/150

提交评论