加入VIP
  • 专属下载特权
  • 现金文档折扣购买
  • VIP免费专区
  • 千万文档免费下载

上传资料

关闭

关闭

关闭

封号提示

内容

首页 设计模式

设计模式.pdf

设计模式

小熊
2012-02-01 0人阅读 举报 0 0 暂无简介

简介:本文档为《设计模式pdf》,可适用于IT/计算机领域

本书设计实例从面向对象的设计中精选出个设计模式总结了面向对象设计中最有价值的经验并且用简洁可复用的形式表达出来。本书分类描述了一组设计良好表达清楚的软件设计模式这些模式在实用环境下有特别有用。目录序言前言读者指南第章引言什么是设计模式SmalltalkMVC中的设计模式描述设计模式设计模式的编目组织编目设计模式怎样解决设计问题寻找合适的对象决定对象的粒度指定对象接口描述对象的实现运用复用机制关联运行时刻和编译时刻的结构设计应支持变化怎样选择设计模式怎样使用设计模式第章实例研究:设计一个文档编辑器设计问题文档结构递归组合图元组合模式格式化封装格式化算法Compositor和Composition策略模式修饰用户界面透明围栏MonoglyphDecorator模式支持多种视感标准对象创建的抽象工厂类和产品类AbstractFactory模式支持多种窗口系统我们是否可以使用AbstractFactory模式封装实现依赖关系Window和WindowImpBridge模式用户操作封装一个请求Command类及其子类撤消和重做命令历史记录Command模式拼写检查和断字处理访问分散的信息封装访问和遍历Iterator类及其子类Iterator模式遍历和遍历过程中的动作封装分析Visitor类及其子类Visitor模式小结第章创建型模式AbstractFactory(抽象工厂)对象创建型模式Builder(生成器)对象创建型模式FactoryMethod(工厂方法)对象创建型模式Prototype(原型)对象创建型模式Singleton(单件)对象创建型模式创建型模式的讨论第章结构型模式Adapter(适配器)类对象结构型模式Bridge(桥接)对象结构型模式Composite(组成)对象结构型模式Decorator(装饰)对象结构型模式FACADE(外观)对象结构型模式Flyweight(享元)对象结构型模式Proxy(代理)对象结构型模式结构型模式的讨论Adapter与BridgeComposite、Decorator与Proxy第章行为模式CHAINOFRESPONSIBILITY(职责链)对象行为型模式COMMAND(命令)对象行为型模式INTERPRETER(解释器)类行为型模式ITERATOR(迭代器)对象行为型模式MEDIATOR(中介者)对象行为型模式MEMENTO(备忘录)对象行为型模式OBSERVER(观察者)对象行为型模式STATE(状态)对象行为型模式STRATEGY(策略)对象行为型模式TEMPLATEMETHOD(模板方法)类行为型模式VISITOR(访问者)对象行为型模式行为模式的讨论封装变化对象作为参数通信应该被封装还是被分布对发送者和接收者解耦总结第章结论设计模式将带来什么一套通用的设计词汇书写文档和学习的辅助手段现有方法的一种补充重构的目标本书简史模式界Alexander的模式语言软件中的模式邀请参与临别感想附录A词汇表附录B图示符号指南附录C基本类参考文献序言所有结构良好的面向对象软件体系结构中都包含了许多模式。实际上当我评估一个面向对象系统的质量时所使用的方法之一就是要判断系统的设计者是否强调了对象之间的公共协同关系。在系统开发阶段强调这种机制的优势在于它能使所生成的系统体系结构更加精巧、简洁和易于理解其程度远远超过了未使用模式的体系结构。模式在构造复杂系统时的重要性早已在其他领域中被认可。特别地ChristopherAlexander和他的同事们可能最先将模式语言(patternlanguage)应用于城市建筑领域他的思想和其他人的贡献已经根植于面向对象软件界。简而言之软件领域中的设计模式为开发人员提供了一种使用专家设计经验的有效途径。在本书中ErichGamma、RichardHelm、RalphJohnson和JohnVlissides介绍了设计模式的原理并且对这些设计模式进行了分类描述。因此该书做出了两个重要的贡献:首先它展示了模式在建造复杂系统过程中所处的角色其次它为如何引用一组精心设计的模式提供了一个实用方法以帮助实际开发者针对特定应用问题使用适当的模式进行设计。我曾荣幸地有机会与本书的部分作者一同进行体系结构设计工作从他们身上我学到了许多东西并相信通过阅读该书你同样也会受益匪浅。Rational软件公司首席科学家GradyBooch前言本书并不是一本介绍面向对象技术或设计的书目前已有不少好书介绍面向对象技术或设计。本书假设你至少已经比较熟悉一种面向对象编程语言并且有一定的面向对象设计经验。当我们提及“类型”和“多态”或“接口”继承与“实现”继承的关系时你应该对这些概念了然于胸而不必迫不及待地翻阅手头的字典。另外这也不是一篇高级专题技术论文而是一本关于设计模式的书它描述了在面向对象软件设计过程中针对特定问题的简洁而优雅的解决方案。设计模式捕获了随时间进化与发展的问题的求解方法因此它们并不是人们从一开始就采用的设计方案。它们反映了不为人知的重新设计和重新编码的成果而这些都来自软件开发者为了设计出灵活可复用的软件而长时间进行的艰苦努力。设计模式捕获了这些解决方案并用简洁易用的方式表达出来。设计模式并不要求使用独特的语言特性也不采用那些足以使你的朋友或老板大吃一惊的神奇的编程技巧。所有的模式均可以用标准的面向对象语言实现这也许有时会比特殊的解法多费一些功夫但是为了增加软件的灵活性和可复用性多做些工作是值得的。一旦你理解了设计模式并且有了一种“Aha!”(而不是“Huh?”)的应用经验和体验后你将用一种非同寻常的方式思考面向对象设计。你将拥有一种深刻的洞察力以帮助你设计出更加灵活的、模块化的、可复用的和易理解的软件这也是你为何着迷于面向对象技术的源动力不是吗?当然还有一些提示和鼓励:第一次阅读此书时你可能不会完全理解它但不必着急我们在起初编写这本书时也没有完全理解它们!请记住这不是一本读完一遍就可以束之高阁的书。我们希望你在软件设计过程中反复参阅此书以获取设计灵感。我们并不认为这组设计模式是完整的和一成不变的它只是我们目前对设计的思考的记录。因此我们欢迎广大读者的批评与指正无论从书中采用的实例、参考还是我们遗漏的已知应用或应该包含的设计模式等方面。你可以通过AddisonWesley写信给我们或发送电子邮件到:designpatternscsuiucedu。你还可以发送邮件“senddesignpatternsource”到designpatternssourcecsuiucedu获取书中的示例代码部分的源代码。另外我们有一个专门的网页报道最新的消息与更新:http:stwwwcsuiuceduuserspatternsDPBookDPBookhtmlEG于加州MountainViewRH于蒙特利尔RJ于伊利诺UrbanaJV于纽约Hawthorne年月下载第章引言设计面向对象软件比较困难而设计可复用的面向对象软件就更加困难。你必须找到相关的对象以适当的粒度将它们归类再定义类的接口和继承层次建立对象之间的基本关系。你的设计应该对手头的问题有针对性同时对将来的问题和需求也要有足够的通用性。你也希望避免重复设计或尽可能少做重复设计。有经验的面向对象设计者会告诉你要一下子就得到复用性和灵活性好的设计即使不是不可能的至少也是非常困难的。一个设计在最终完成之前常要被复用好几次而且每一次都有所修改。有经验的面向对象设计者的确能做出良好的设计而新手则面对众多选择无从下手总是求助于以前使用过的非面向对象技术。新手需要花费较长时间领会良好的面向对象设计是怎么回事。有经验的设计者显然知道一些新手所不知道的东西这又是什么呢?内行的设计者知道:不是解决任何问题都要从头做起。他们更愿意复用以前使用过的解决方案。当找到一个好的解决方案他们会一遍又一遍地使用。这些经验是他们成为内行的部分原因。因此你会在许多面向对象系统中看到类和相互通信的对象(communicatingobject)的重复模式。这些模式解决特定的设计问题使面向对象设计更灵活、优雅最终复用性更好。它们帮助设计者将新的设计建立在以往工作的基础上复用以往成功的设计方案。一个熟悉这些模式的设计者不需要再去发现它们而能够立即将它们应用于设计问题中。以下类比可以帮助说明这一点。小说家和剧本作家很少从头开始设计剧情。他们总是沿袭一些业已存在的模式像“悲剧性英雄”模式(《麦克白》、《哈姆雷特》等)或“浪漫小说”模式(存在着无数浪漫小说)。同样地面向对象设计员也沿袭一些模式像“用对象表示状态”和“修饰对象以便于你能容易地添加删除属性”等。一旦懂得了模式许多设计决策自然而然就产生了。我们都知道设计经验的重要价值。你曾经多少次有过这种感觉你已经解决过了一个问题但就是不能确切知道是在什么地方或怎么解决的?如果你能记起以前问题的细节和怎么解决它的你就可以复用以前的经验而不需要重新发现它。然而我们并没有很好记录下可供他人使用的软件设计经验。这本书的目的就是将面向对象软件的设计经验作为设计模式记录下来。每一个设计模式系统地命名、解释和评价了面向对象系统中一个重要的和重复出现的设计。我们的目标是将设计经验以人们能够有效利用的形式记录下来。鉴于此目的我们编写了一些最重要的设计模式并以编目分类的形式将它们展现出来。设计模式使人们可以更加简单方便地复用成功的设计和体系结构。将已证实的技术表述成设计模式也会使新系统开发者更加容易理解其设计思路。设计模式帮助你做出有利于系统复用的选择避免设计损害了系统复用性。通过提供一个显式类和对象作用关系以及它们之间潜在联系的说明规范设计模式甚至能够提高已有系统的文档管理和系统维护的有效性。简而言之设计模式可以帮助设计者更快更好地完成系统设计。本书中涉及的设计模式并不描述新的或未经证实的设计我们只收录那些在不同系统中多次使用过的成功设计。这些设计的绝大部分以往并无文档记录它们或是来源于面向对象设计者圈子里的非正式交流或是来源于某些成功的面向对象系统的某些部分但对设计新手来说这些东西是很难学得到的。尽管这些设计不包含新的思路但我们用一种新的、便于理解的方式将其展现给读者即:具有统一格式的、已分类编目的若干组设计模式。尽管该书涉及较多的内容但书中讨论的设计模式仅仅包含了一个设计行家所知道的部分。书中没有讨论与并发或分布式或实时程序设计有关的模式也没有收录面向特定应用领域的模式。本书并不准备告诉你怎样构造用户界面、怎样写设备驱动程序或怎样使用面向对象数据库这些方面都有自己的模式将这些模式分类编目也是件很有意义的事。什么是设计模式ChristopherAlexander说过:“每一个模式描述了一个在我们周围不断重复发生的问题以及该问题的解决方案的核心。这样你就能一次又一次地使用该方案而不必做重复劳动”AIS第页。尽管Alexander所指的是城市和建筑模式但他的思想也同样适用于面向对象设计模式只是在面向对象的解决方案里我们用对象和接口代替了墙壁和门窗。两类模式的核心都在于提供了相关问题的解决方案。一般而言一个模式有四个基本要素:模式名称(patternname)一个助记名它用一两个词来描述模式的问题、解决方案和效果。命名一个新的模式增加了我们的设计词汇。设计模式允许我们在较高的抽象层次上进行设计。基于一个模式词汇表我们自己以及同事之间就可以讨论模式并在编写文档时使用它们。模式名可以帮助我们思考便于我们与其他人交流设计思想及设计结果。找到恰当的模式名也是我们设计模式编目工作的难点之一。问题(problem)描述了应该在何时使用模式。它解释了设计问题和问题存在的前因后果它可能描述了特定的设计问题如怎样用对象表示算法等。也可能描述了导致不灵活设计的类或对象结构。有时候问题部分会包括使用模式必须满足的一系列先决条件。解决方案(solution)描述了设计的组成成分它们之间的相互关系及各自的职责和协作方式。因为模式就像一个模板可应用于多种不同场合所以解决方案并不描述一个特定而具体的设计或实现而是提供设计问题的抽象描述和怎样用一个具有一般意义的元素组合(类或对象组合)来解决这个问题。效果(consequences)描述了模式应用的效果及使用模式应权衡的问题。尽管我们描述设计决策时并不总提到模式效果但它们对于评价设计选择和理解使用模式的代价及好处具有重要意义。软件效果大多关注对时间和空间的衡量它们也表述了语言和实现问题。因为复用是面向对象设计的要素之一所以模式效果包括它对系统的灵活性、扩充性或可移植性的影响显式地列出这些效果对理解和评价这些模式很有帮助。出发点的不同会产生对什么是模式和什么不是模式的理解不同。一个人的模式对另一个人来说可能只是基本构造部件。本书中我们将在一定的抽象层次上讨论模式。《设计模式》并不描述链表和hash表那样的设计尽管它们可以用类来封装也可复用也不包括那些复杂的、特定领域内的对整个应用或子系统的设计。本书中的设计模式是对被用来在特定场景下解决一般设计问题的类和相互通信的对象的描述。一个设计模式命名、抽象和确定了一个通用设计结构的主要方面这些设计结构能被用设计模式:可复用面向对象软件的基础下载来构造可复用的面向对象设计。设计模式确定了所包含的类和实例它们的角色、协作方式以及职责分配。每一个设计模式都集中于一个特定的面向对象设计问题或设计要点描述了什么时候使用它在另一些设计约束条件下是否还能使用以及使用的效果和如何取舍。既然我们最终要实现设计设计模式还提供了C和Smalltalk示例代码来阐明其实现。虽然设计模式描述的是面向对象设计但它们都基于实际的解决方案这些方案的实现语言是Smalltalk和C等主流面向对象编程语言而不是过程式语言(Pascal、C、Ada)或更具动态特性的面向对象语言(CLOS、Dylan、Self)。我们从实用角度出发选择了Smalltalk和C因为在这些语言的使用上我们积累了许多经验况且它们也变得越来越流行。程序设计语言的选择非常重要它将影响人们理解问题的出发点。我们的设计模式采用了Smalltalk和C层的语言特性这个选择实际上决定了哪些机制可以方便地实现而哪些则不能。若我们采用过程式语言可能就要包括诸如“继承”、“封装”和“多态”的设计模式。相应地一些特殊的面向对象语言可以直接支持我们的某些模式例如:CLOS支持多方法(multimethod)概念这就减少了Visitor模式的必要性。事实上Smalltalk和C已有足够的差别来说明对某些模式一种语言比另一种语言表述起来更容易一些(参见节Iterator模式)。SmalltalkMVC中的设计模式在Smalltalk中类的模型视图控制器(ModelViewController)三元组(MVC)被用来构建用户界面。透过MVC来看设计模式将帮助我们理解“模式”这一术语的含义。MVC包括三类对象。模型Model是应用对象视图View是它在屏幕上的表示控制器Controller定义用户界面对用户输入的响应方式。不使用MVC用户界面设计往往将这些对象混在一起而MVC则将它们分离以提高灵活性和复用性。MVC通过建立一个“订购通知”协议来分离视图和模型。视图必须保证它的显示正确地反映了模型的状态。一旦模型的数据发生变化模型将通知有关的视图每个视图相应地得到刷新自己的机会。这种方法可以让你为一个模型提供不同的多个视图表现形式也能够为一个模型创建新的视图而无须重写模型。下图显示了一个模型和三个视图(为了简单起见我们省略了控制器)。模型包含一些数据值视图通过电子表格、柱状图、饼图这些不同的方式来显示这些数据。当模型的数据发生变化时模型就通知它的视图而视图将与模型通信以访问这些数据值。第章引言下载视图模型表面上看这个例子反映了将视图和模型分离的设计然而这个设计还可用于解决更一般的问题:将对象分离使得一个对象的改变能够影响另一些对象而这个对象并不需要知道那些被影响的对象的细节。这个更一般的设计被描述成Observer()模式。MVC的另一个特征是视图可以嵌套。例如按钮控制面板可以用一个嵌套了按钮的复杂视图来实现。对象查看器的用户界面可由嵌套的视图构成这些视图又可复用于调试器。MVC用View类的子类CompositeView类来支持嵌套视图。CompositeView类的对象行为上类似于View类对象一个组合视图可用于任何视图可用的地方但是它包含并管理嵌套视图。上例反映了可以将组合视图与其构件平等对待的设计同样地该设计也适用于更一般的问题:将一些对象划为一组并将该组对象当作一个对象来使用。这个设计被描述为Composite()模式该模式允许你创建一个类层次结构一些子类定义了原子对象(如Button)而其他类定义了组合对象(CompositeView)这些组合对象是由原子对象组合而成的更复杂的对象。MVC允许你在不改变视图外观的情况下改变视图对用户输入的响应方式。例如你可能希望改变视图对键盘的响应方式或希望使用弹出菜单而不是原来的命令键方式。MVC将响应机制封装在Controller对象中。存在着一个Controller的类层次结构使得可以方便地对原有Controller做适当改变而创建新的Controller。View使用Controller子类的实例来实现一个特定的响应策略。要实现不同的响应策略只要用不同种类的Controller实例替换即可。甚至可以在运行时刻通过改变View的Controller来改变View对用户输入的响应方式。例如一个View可以被禁止接收任何输入只需给它一个忽略输入事件的Controller。ViewController关系是Strategy()模式的一个例子。一个策略是一个表述算法的对象。当你想静态或动态地替换一个算法或你有很多不同的算法或算法中包含你想封装的复杂数据结构这时策略模式是非常有用的。MVC还使用了其他的设计模式如:用来指定视图缺省控制器的FactoryMethod()和用来增加视图滚动的Decorator()。但是MVC的主要关系还是由Observer、Composite和Strategy三个设计模式给出的。描述设计模式我们怎样描述设计模式呢?图形符号虽然很重要也很有用却还远远不够它们只是将设计过程的结果简单记录为类和对象之间的关系。为了达到设计复用我们必须同时记录设计产生的决定过程、选择过程和权衡过程。具体的例子也是很重要的它们让你看到实际的设计。我们将用统一的格式描述设计模式每一个模式根据以下的模板被分成若干部分。模板具有统一的信息描述结构有助于你更容易地学习、比较和使用设计模式。模式名和分类模式名简洁地描述了模式的本质。一个好的名字非常重要因为它将成为你的设计词汇表中的一部分。模式的分类反映了我们将在节介绍的方案。意图是回答下列问题的简单陈述:设计模式是做什么的?它的基本原理和意图是什么?它解设计模式:可复用面向对象软件的基础下载决的是什么样的特定设计问题?别名模式的其他名称。动机用以说明一个设计问题以及如何用模式中的类、对象来解决该问题的特定情景。该情景会帮助你理解随后对模式更抽象的描述。适用性什么情况下可以使用该设计模式?该模式可用来改进哪些不良设计?你怎样识别这些情况?结构采用基于对象建模技术(OMT)RBP的表示法对模式中的类进行图形描述。我们也使用了交互图JCJOBOO来说明对象之间的请求序列和协作关系。附录B详细描述了这些表示法。参与者指设计模式中的类和或对象以及它们各自的职责。协作模式的参与者怎样协作以实现它们的职责。效果模式怎样支持它的目标?使用模式的效果和所需做的权衡取舍?系统结构的哪些方面可以独立改变?实现实现模式时需要知道的一些提示、技术要点及应避免的缺陷以及是否存在某些特定于实现语言的问题。代码示例用来说明怎样用C或Smalltalk实现该模式的代码片段。已知应用实际系统中发现的模式的例子。每个模式至少包括了两个不同领域的实例。相关模式与这个模式紧密相关的模式有哪些?其间重要的不同之处是什么?这个模式应与哪些其他模式一起使用?附录提供的背景资料将帮助你理解模式以及关于模式的讨论。附录A给出了我们使用的术语列表。前面已经提到过的附录B则给出了各种表示法我们也会在以后的讨论中简单介绍它们。最后附录C给出了我们在例子中使用的各基本类的源代码。设计模式的编目从第章开始的模式目录中共包含个设计模式。它们的名字和意图列举如下以使你有个基本了解。每个模式名后括号中标出模式所在的章节(我们整本书都将遵从这个约定)。AbstractFactory():提供一个创建一系列相关或相互依赖对象的接口而无需指定它们具体的类。第章引言下载Adapter():将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。Bridge():将抽象部分与它的实现部分分离使它们都可以独立地变化。Builder():将一个复杂对象的构建与它的表示分离使得同样的构建过程可以创建不同的表示。ChainofResponsibility():为解除请求的发送者和接收者之间耦合而使多个对象都有机会处理这个请求。将这些对象连成一条链并沿着这条链传递该请求直到有一个对象处理它。Command():将一个请求封装为一个对象从而使你可用不同的请求对客户进行参数化对请求排队或记录请求日志以及支持可取消的操作。Composite():将对象组合成树形结构以表示“部分整体”的层次结构。Composite使得客户对单个对象和复合对象的使用具有一致性。Decorator():动态地给一个对象添加一些额外的职责。就扩展功能而言Decorator模式比生成子类方式更为灵活。Facade():为子系统中的一组接口提供一个一致的界面Facade模式定义了一个高层接口这个接口使得这一子系统更加容易使用。FactoryMethod():定义一个用于创建对象的接口让子类决定将哪一个类实例化。FactoryMethod使一个类的实例化延迟到其子类。Flyweight():运用共享技术有效地支持大量细粒度的对象。Interpreter():给定一个语言,定义它的文法的一种表示并定义一个解释器,该解释器使用该表示来解释语言中的句子。Iterator():提供一种方法顺序访问一个聚合对象中各个元素,而又不需暴露该对象的内部表示。Mediator():用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用从而使其耦合松散而且可以独立地改变它们之间的交互。Memento():在不破坏封装性的前提下捕获一个对象的内部状态并在该对象之外保存这个状态。这样以后就可将该对象恢复到保存的状态。Observer():定义对象间的一种一对多的依赖关系,以便当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动刷新。Prototype():用原型实例指定创建对象的种类并且通过拷贝这个原型来创建新的对象。Proxy():为其他对象提供一个代理以控制对这个对象的访问。Singleton():保证一个类仅有一个实例并提供一个访问它的全局访问点。State():允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它所属的类。Strategy():定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。本模式使得算法的变化可独立于使用它的客户。TemplateMethod():定义一个操作中的算法的骨架而将一些步骤延迟到子类中。TemplateMethod使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。设计模式:可复用面向对象软件的基础下载Visitor():表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。组织编目设计模式在粒度和抽象层次上各不相同。由于存在众多的设计模式我们希望用一种方式将它们组织起来。这一节将对设计模式进行分类以便于我们对各族相关的模式进行引用。分类有助于更快地学习目录中的模式且对发现新的模式也有指导作用如表所示。表设计模式空间目的创建型结构型行为型范围类FactoryMethod()Adapter(类)()Interpreter()TemplateMethod()对象AbstractFactory()Adapter(对象)()ChainofResponsibility()Builder()Bridge()Command()Prototype()Composite()Iterator()Singleton()Decorator()Mediator()Facade()Memento()Flyweight()Observer()Proxy()State()Strategy()Visitor()我们根据两条准则(表)对模式进行分类。第一是目的准则即模式是用来完成什么工作的。模式依据其目的可分为创建型(Creational)、结构型(Structural)、或行为型(Behavioral)三种。创建型模式与对象的创建有关结构型模式处理类或对象的组合行为型模式对类或对象怎样交互和怎样分配职责进行描述。第二是范围准则指定模式主要是用于类还是用于对象。类模式处理类和子类之间的关系这些关系通过继承建立是静态的在编译时刻便确定下来了。对象模式处理对象间的关系这些关系在运行时刻是可以变化的更具动态性。从某种意义上来说几乎所有模式都使用继承机制所以“类模式”只指那些集中于处理类间关系的模式而大部分模式都属于对象模式的范畴。创建型类模式将对象的部分创建工作延迟到子类而创建型对象模式则将它延迟到另一个对象中。结构型类模式使用继承机制来组合类而结构型对象模式则描述了对象的组装方式。行为型类模式使用继承描述算法和控制流而行为型对象模式则描述一组对象怎样协作完成单个对象所无法完成的任务。还有其他组织模式的方式。有些模式经常会被绑在一起使用例如Composite常和Iterator或Visitor一起使用有些模式是可替代的例如Prototype常用来替代AbstractFactory有些模式尽管使用意图不同但产生的设计结果是很相似的例如Composite和Decorator的结构图是相似的。还有一种方式是根据模式的“相关模式”部分所描述的它们怎样互相引用来组织设计模式。图给出了模式关系的图形说明。第章引言下载显然存在着许多组织设计模式的方法。从多角度去思考模式有助于对它们的功能、差异和应用场合的更深入理解。图设计模式之间的关系设计模式怎样解决设计问题设计模式采用多种方法解决面向对象设计者经常碰到的问题。这里给出几个问题以及使用设计模式解决它们的方法。寻找合适的对象面向对象程序由对象组成对象包括数据和对数据进行操作的过程过程通常称为方法或操作。对象在收到客户的请求(或消息)后执行相应的操作。设计模式:可复用面向对象软件的基础下载保存迭代状态创建组合给对象增加职责改变外表改变内容定义算法步骤动态地配置工厂用工厂方法实现单个实例单个实例增加操作增加操作共享组合共享策略定义语法共享终结符共享状态定义遍历定义链避免滞后枚举子女使用组合命令客户请求是使对象执行操作的唯一方法操作又是对象改变内部数据的唯一方法。由于这些限制对象的内部状态是被封装的它不能被直接访问它的表示对于对象外部是不可见的。面向对象设计最困难的部分是将系统分解成对象集合。因为要考虑许多因素:封装、粒度、依赖关系、灵活性、性能、演化、复用等等它们都影响着系统的分解并且这些因素通常还是互相冲突的。面向对象设计方法学支持许多设计方法。你可以写出一个问题描述挑出名词和动词进而创建相应的类和操作或者你可以关注于系统的协作和职责关系或者你可以对现实世界建模再将分析时发现的对象转化至设计中。至于哪一种方法最好并无定论。设计的许多对象来源于现实世界的分析模型。但是设计结果所得到的类通常在现实世界中并不存在有些是像数组之类的低层类而另一些则层次较高。例如Composite()模式引入了统一对待现实世界中并不存在的对象的抽象方法。严格反映当前现实世界的模型并不能产生也能反映将来世界的系统。设计中的抽象对于产生灵活的设计是至关重要的。设计模式帮你确定并不明显的抽象和描述这些抽象的对象。例如描述过程或算法的对象现实中并不存在但它们却是设计的关键部分。Strategy()模式描述了怎样实现可互换的算法族。State()模式将实体的每一个状态描述为一个对象。这些对象在分析阶段甚至在设计阶段的早期都并不存在后来为使设计更灵活、复用性更好才将它们发掘出来。决定对象的粒度对象在大小和数目上变化极大。它们能表示下自硬件或上自整个应用的任何事物。那么我们怎样决定一个对象应该是什么呢?设计模式很好地讲述了这个问题。Facade()模式描述了怎样用对象表示完整的子系统Flyweight()模式描述了如何支持大量的最小粒度的对象。其他一些设计模式描述了将一个对象分解成许多小对象的特定方法。AbstractFactory()和Builder()产生那些专门负责生成其他对象的对象。Visitor()和Command()生成的对象专门负责实现对其他对象或对象组的请求。指定对象接口对象声明的每一个操作指定操作名、作为参数的对象和返回值这就是所谓的操作的型构(signature)。对象操作所定义的所有操作型构的集合被称为该对象的接口(interface)。对象接口描述了该对象所能接受的全部请求的集合任何匹配对象接口中型构的请求都可以发送给该对象。类型(type)是用来标识特定接口的一个名字。如果一个对象接受“Window”接口所定义的所有操作请求那么我们就说该对象具有“Window”类型。一个对象可以有许多类型并且不同的对象可以共享同一个类型。对象接口的某部分可以用某个类型来刻画而其他部分则可用其他类型刻画。两个类型相同的对象只需要共享它们的部分接口。接口可以包含其他接口作为子集。当一个类型的接口包含另一个类型的接口时我们就说它是另一个类型的子类型(subtype)另一个类型称之为它的超类型(supertype)。我们常说子类型继承了它的超类型的接口。第章引言下载在面向对象系统中接口是基本的组成部分。对象只有通过它们的接口才能与外部交流如果不通过对象的接口就无法知道对象的任何事情也无法请求对象做任何事情。对象接口与其功能实现是分离的不同对象可以对请求做不同的实现也就是说两个有相同接口的对象可以有完全不同的实现。当给对象发送请求时所引起的具体操作既与请求本身有关又与接受对象有关。支持相同请求的不同对象可能对请求激发的操作有不同的实现。发送给对象的请求和它的相应操作在运行时刻的连接就称之为动态绑定(dynamicbinding)。动态绑定是指发送的请求直到运行时刻才受你的具体的实现的约束。因而在知道任何有正确接口的对象都将接受此请求时你可以写一个一般的程序它期待着那些具有该特定接口的对象。进一步讲动态绑定允许你在运行时刻彼此替换有相同接口的对象。这种可替换性就称为多态(polymorphism)它是面向对象系统中的核心概念之一。多态允许客户对象仅要求其他对象支持特定接口除此之外对其假设几近于无。多态简化了客户的定义使得对象间彼此独立并可以在运行时刻动态改变它们相互的关系。设计模式通过确定接口的主要组成成分及经接口发送的数据类型来帮助你定义接口。设计模式也许还会告诉你接口中不应包括哪些东西。Memento()模式是一个很好的例子它描述了怎样封装和保存对象内部的状态以便一段时间后对象能恢复到这一状态。它规定了Memento对象必须定义两个接口:一个允许客户保持和复制memento的限制接口和一个只有原对象才能使用的用来储存和提取memento中状态的特权接口。设计模式也指定了接口之间的关系。特别地它们经常要求一些类具有相似的接口或它们对一些类的接口做了限制。例如Decorator()和Proxy()模式要求Decorator和Proxy对象的接口与被修饰的对象和受委托的对象一致。而Visitor()模式中Visitor接口必须反映出visitor能访问的对象的所有类。描述对象的实现至此我们很少提及到实际上怎么去定义一个对象。对象的实现是由它的类决定的类指定了对象的内部数据和表示也定义了对象所能完成的操作如右图所示。我们基于OMT的表示法将类描述成一个矩形其中的类名以黑体表示的。操作在类名下面以常规字体表示。类所定义的任何数据都在操作的下面。类名与操作之间以及操作与数据之间用横线分割。返回类型和实例变量类型是可选的因为我们并未假设一定要用具有静态类型的实现语言。对象通过实例化类来创建此对象被称为该类的实例。当实例化类时要给对象的内部数据(由实例变量组成)分配存储空间并将操作与这些数据联系起来。对象的许多类似实例是由实例化同一个类来创建的。下图中的虚箭头线表示一个类实例化另一个类的对象箭头指向被实例化的对象的类。新的类可以由已存在的类通过类继承(classinheritance)来定义。当子类(subclass)继承父类设计模式:可复用面向对象软件的基础下载(parentclass)时子类包含了父类定义的所有数据和操作。子类的实例对象包含所有子类和父类定义的数据且它们能完成子类和父类定义的所有操作。我们以竖线和三角表示子类关系如下图所示。抽象类(abstractclass)的主要目的是为它的子类定义公共接口。一个抽象类将把它的部分或全部操作的实现延迟到子类中因此一个抽象类不能被实例化。在抽象类中定义却没有实现的操作被称为抽象操作(abstractoperation)。非抽象类称为具体类(concreteclass)。子类能够改进和重新定义它们父类的操作。更具体地说类能够重定义(override)父类定义的操作重定义使得子类能接管父类对请求的处理操作。类继承允许你只需简单的扩展其他类就可以定义新类从而可以很容易地定义具有相近功能的对象族。抽象类的类名以斜体表示以与具体类相区别。抽象操作也用斜体表示。图中可以包括实现操作的伪代码如果这样则代码将出现在带有摺角的框中并用虚线将该摺角框与代码所实现的操作相连图示如下。混入类(mixinclass)是给其他类提供可选择的接口或功能的类。它与抽象类一样不能实例化。混入类要求多继承图示如下。类继承与接口继承的比较理解对象的类(class)与对象的类型(type)之间的差别非常重要。一个对象的类定义了对象是怎样实现的同时也定义了对象的内部状态和操作的实现。但是对象的类型只与它的接口有关接口即对象能响应的请求的集合。一个对象可以有多个第章引言下载类型不同类的对象可以有相同的类型。当然对象的类和类型是有紧密关系的。因为类定义了对象所能执行的操作也定义了对象的类型。当我们说一个对象是一个类的实例时即指该对象支持类所定义的接口。C和Eiffel语言的类既指定对象的类型又指定对象的实现。Smalltalk程序不声明变量的类型所以编译器不检查赋给变量的对象类型是否是该变量的类型的子类型。发送消息时需要检查消息接收者是否实现了该消息但不检查接收者是否是某个特定类的实例。理解类继承和接口继承(或子类型化)之间的差别也十分重要。类继承根据一个对象的实现定义了另一个对象的实现。简而言之它是代码和表示的共享机制。然而接口继承(或子类型化)描述了一个对象什么时候能被用来替代另一个对象。因为许多语言并不显式地区分这两个概念所以容易被混淆。在C和Eiffel语言中继承既指接口的继承又指实现的继承。C中接口继承的标准方法是公有继承一个含(纯)虚成员函数的类。C中纯接口继承接近于公有继承纯抽象类纯实现继承或纯类继承接近于私有继承。Smalltalk中的继承只指实现继承。只要任何类的实例支持对变量值的操作你就可以将这些实例赋给变量。尽管大部分程序设计语言并不区分接口继承和实现继承的差别但使用中人们还是分别对待它们的。Smalltalk程序员通常将子类当作子类型(尽管有一些熟知的例外情况Coo)C程序员通过抽象类所定义的类型来操纵对象。很多设计模式依赖于这种差别。例如ChainofResponsibility()模式中的对象必须有一个公共的类型但一般情况下它们不具有公共的实现。在Composite()模式中构件定义了一个公共的接口但Composite通常定义一个公共的实现。Command()、Observer()、State()和Strategy()通常纯粹作为接口的抽象类来实现。对接口编程而不是对实现编程类继承是一个通过复用父类功能而扩展应用功能的基本机制。它允许你根据旧对象快速定义新对象。它允许你从已存在的类中继承所

用户评价(8)

  • superq 文字版,很清楚.非常感谢.

    2013-06-15 07:54:49

  • 落叶归根 非常感谢

    2013-03-02 20:15:32

  • tiramisu1017 经典的书,谢谢分享,非常清晰

    2013-01-15 04:16:34

  • 山里来的鱼 很经典的一本书,谢谢了

    2012-12-27 20:20:42

  • 10.44.7.248 质量非常好,经典书籍,经典资源啊

    2012-11-19 13:43:31

点击加载更多内容
关闭

新课改视野下建构高中语文教学实验成果报告(32KB)

抱歉,积分不足下载失败,请稍后再试!

提示

试读已结束,如需要继续阅读或者下载,敬请购买!

文档小程序码

使用微信“扫一扫”扫码寻找文档

1

打开微信

2

扫描小程序码

3

发布寻找信息

4

等待寻找结果

我知道了
评分:

/49

设计模式

仅供在线阅读

VIP

在线
客服

免费
邮箱

爱问共享资料服务号

扫描关注领取更多福利