常用设计模式及java程序.pdf
《常用设计模式及java程序.pdf》由会员分享,可在线阅读,更多相关《常用设计模式及java程序.pdf(76页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、http:/ 咨询QQ:460190900 Java私塾跟我学系列JAVA篇 欢迎大家前来北京JAVA私塾报名学习 联系电话:13651249175 张老师 308 第二部分第二部分 常用设计模式常用设计模式 及及 Java 程序设计程序设计 http:/ 咨询QQ:460190900 Java私塾跟我学系列JAVA篇 欢迎大家前来北京JAVA私塾报名学习 联系电话:13651249175 张老师 309 第一章 设计模式基础 教学目标:教学目标:i掌握设计模式的基本概念掌握设计模式的基本概念 i掌握模式在设计中的应用掌握模式在设计中的应用 i掌握程序设计的基本要求掌握程序设计的基本要求 ht
2、tp:/ 咨询QQ:460190900 Java私塾跟我学系列JAVA篇 欢迎大家前来北京JAVA私塾报名学习 联系电话:13651249175 张老师 310 一:什么是设计模式一:什么是设计模式 在面向对象的软件设计中,总是希望避免重复设计或尽可能少做重复设计。有经验的面向对象设计者的确能做出良好的设计,而新手则面对众多选择无从下手,总是求助于以前使用过的非面向对象技术。有经验的设计者显然知道一些新手所不知道的东西,这又是什么呢?内行的设计者知道:不是解决任何问题都要从头做起。他们更愿意复用以前使用过的解决方案。当找到一个好的解决方案,他们会一遍又一遍地使用。这些经验是他们成为内行的部分原
3、因。它们帮助设计者将新的设计建立在以往工作的基础上,复用以往成功的设计方案。一个熟悉这些模式的设计者不需要再去发现它们,而能够立即将它们应用于设计问题中。设计模式使人们可以更加简单方便地复用成功的设计和体系结构。将已证实的技术表述成设计模式也会使新系统开发者更加容易理解其设计思路。设计模式帮助你做出有利于系统复用的选择,避免设计损害了系统复用性。通过提供一个显式类和对象作用关系以及它们之间潜在联系的说明规范,设计模式甚至能够提高已有系统的文档管理和系统维护的有效性。简而言之,设计模式可以帮助设计者更快更好地完成系统设计。1:什么是设计模式:什么是设计模式 Christopher Alexand
4、er 说过:“每一个模式描述了一个在我们周围不断重复发生的问题,以及该问题的解决方案的核心。这样,你就能一次又一次地使用该方案而不必做重复劳动”。尽管A l e x a n d e r所指的是城市和建筑模式,但他的思想也同样适用于面向对象设计模式,只是在面向对象的解决方案里,我们用对象和接口代替了墙壁和门窗。两类模式的核心都在于提供了相关问题的解决方案。一般而言,一个模式有四个基本要素:模式名称(模式名称(pattern name)一个助记名,它用一两个词来描述模式的问题、解决方案和效果。问题问题(problem)描述了应该在何时使用模式。它解释了设计问题和问题存在的前因后果,它可能描述了特定
5、的设计问题,如怎样用对象表示算法等。也可能描述了导致不灵活设计的类或对象结构。有时候,问题部分会包括使用模式必须满足的一系列先决条件。解决方案解决方案(solution)描述了设计的组成成分,它们之间的相互关系及各自的职责和协作方式。因为模式就像一个模板,可应用于多种不同场合,所以解决方案并不描述一个特定而具体的设计或实现,而是提供设计问题的抽象描述和怎样用一个具有一般意义的元素组合(类或对象组合)来解决这个问题。效果效果(consequences)描述了模式应用的效果及使用模式应权衡的问题。尽管我们描述设计决策时,并不总提到模式效果,但它们对于评价设计选择和理解使用模式的代价及好处具有重要意
6、义。软件效果大多关注对时间和空间的衡量,它们也表述了语言和实现问题。因为复用是面向对象设计的要素之一,所以模式效果包括它对系统的灵活性、扩充性或可移植性的影响,显式地列出这些效果对理解和评价这些模式很有帮助。出发点的不同会产生对什么是模式和什么不是模式的理解不同。一个人的模式对另一个人来说可能只是基本构造部件。http:/ 咨询QQ:460190900 Java私塾跟我学系列JAVA篇 欢迎大家前来北京JAVA私塾报名学习 联系电话:13651249175 张老师 311 二:设计模式怎样解决设计问题二:设计模式怎样解决设计问题 设计模式采用多种方法解决面向对象设计者经常碰到的问题。这里给出几
7、个问题以及使用设计模式解决它们的方法。1:寻找合适的对象寻找合适的对象 面向对象程序由对象组成,对象包括数据和对数据进行操作的过程,过程通常称为方法或操作。对象在收到客户的请求(或消息)后,执行相应的操作。客户请求是使对象执行操作的唯一方法,操作又是对象改变内部数据的唯一方法。由于这些限制,对象的内部状态是被封装的,它不能被直接访问,它的表示对于对象外部是不可见的。面向对象设计最困难的部分是将系统分解成对象集合。因为要考虑许多因素:封装、粒度、依赖关系、灵活性、性能、演化、复用等等,它们都影响着系统的分解,并且这些因素通常还是互相冲突的。面向对象设计方法学支持许多设计方法。你可以写出一个问题描
8、述,挑出名词和动词,进而创建相应的类和操作;或者,你可以关注于系统的协作和职责关系;或者,你可以对现实世界建模,再将分析时发现的对象转化至设计中。至于哪一种方法最好,并无定论。设计的许多对象来源于现实世界的分析模型。但是,设计结果所得到的类通常在现实世界中并不存在,有些是像数组之类的低层类,而另一些则层次较高。设计中的抽象对于产生灵活的设计是至关重要的。设计模式帮你确定并不明显的抽象和描述这些抽象的对象。例如,描述过程或算法的对象现实中并不存在,但它们却是设计的关键部分。2 决定对象的粒度决定对象的粒度 对象在大小和数目上变化极大。它们能表示下自硬件或上自整个应用的任何事物。那么我们怎样决定一
9、个对象应该是什么呢?设计模式很好地讲述了这个问题,具体的我们会在以后的设计模式的学习中讲到。3 指定对象接口指定对象接口 对象声明的每一个操作指定操作名、作为参数的对象和返回值,这就是所谓的操作的型构(s i g n a t u r e)。对象操作所定义的所有操作型构的集合被称为该对象的接口(i n t e r f a c e)。对象接口描述了该对象所能接受的全部请求的集合,任何匹配对象接口中型构的请求都可以发送给该对象。类型(type)是用来标识特定接口的一个名字。如果一个对象接受“Wi n d o w”接口所定义的所有操作请求,那么我们就说该对象具有“Wi n d o w”类型。一个对象可
10、以有许多类型,并且不同的对象可以共享同一个类型。对象接口的某部分可以用某个类型来刻画,而其他部分则可用其他类型刻画。两个类型相同的对象只需要共享它们的部分接口。接口可以包含其他接口作为子集。当一个类型的接口包含另一个类型的接口时,我们就说它是另一个类型的子类型(s u b t y p e),另一个类型称之为它的超类型(s u p e r t y p e)。我们常说子类型继承了它的超类型的接口。在面向对象系统中,接口是基本的组成部分。对象只有通过它们的接口才能与外部交流,如果不通过对象的接口就无法知道对象的任何事情,也无法请求对象做任何事情。对象接口与其功能实现是分离的,不同对象可以对请求做不同
11、的实现,也就是说,两个有相同接口的对象可以有完全不同的实现。当给对象发送请求时,所引起的具体操作既与请求本身有关又与接受对象有关。支持相同请求的不同对象可能对请求激发的操作有不同的实现。发送给对象的请求和它的相应操作在运行时刻的http:/ 咨询QQ:460190900 Java私塾跟我学系列JAVA篇 欢迎大家前来北京JAVA私塾报名学习 联系电话:13651249175 张老师 312 连接就称之为动态绑定(dynamic binding)。动态绑定是指发送的请求直到运行时刻才受你的具体的实现的约束。因而,在知道任何有正确接口的对象都将接受此请求时,你可以写一个一般的程序,它期待着那些具有
12、该特定接口的对象。进一步讲,动态绑定允许你在运行时刻彼此替换有相同接口的对象。这种可替换性就称为多态(p o l y m o r p h i s m),它是面向对象系统中的核心概念之一。多态允许客户对象仅要求其他对象支持特定接口,除此之外对其假设几近于无。多态简化了客户的定义,使得对象间彼此独立,并可以在运行时刻动态改变它们相互的关系。设计模式通过确定接口的主要组成成分及经接口发送的数据类型,来帮助你定义接口。设计模式也许还会告诉你接口中不应包括哪些东西。设计模式也指定了接口之间的关系。4 描述对象的实现描述对象的实现 至此,我们很少提及到实际上怎么去定义一个对象。对象的实现是由它的类决定的,
13、类指定了对象的内部数据和表示,也定义了对象所能完成的操作。对象通过实例化类来创建,此对象被称为该类的实例。当实例化类时,要给对象的内部数据(由实例变量组成)分配存储空间,并将操作与这些数据联系起来。对象的许多类似实例是由实例化同一个类来创建的。4.1.类继承与接口继承的比较类继承与接口继承的比较 理解对象的类(c l a s s)与对象的类型(t y p e)之间的差别非常重要。一个对象的类定义了对象是怎样实现的,同时也定义了对象的内部状态和操作的实现。但是对象的类型只与它的接口有关,接口即对象能响应的请求的集合。一个对象可以有多个类型,不同类的对象可以有相同的类型。当然,对象的类和类型是有紧
14、密关系的。因为类定义了对象所能执行的操作,也定义了对象的类型。当我们说一个对象是一个类的实例时,即指该对象支持类所定义的接口。理解类继承和接口继承(或子类型化)之间的差别也十分重要。类继承根据一个对象的实现定义了另一个对象的实现。简而言之,它是代码和表示的共享机制。然而,接口继承(或子类型化)描述了一个对象什么时候能被用来替代另一个对象。4.2.对接口编程,而不是对实现编程对接口编程,而不是对实现编程 类继承是一个通过复用父类功能而扩展应用功能的基本机制。它允许你根据旧对象快速定义新对象。它允许你从已存在的类中继承所需要的绝大部分功能,从而几乎无需任何代价就可以获得新的实现。然而,实现的复用只
15、是成功的一半,继承所拥有的定义具有相同接口的对象族的能力也是很重要的(通常可以从抽象类来继承)。为什么?因为多态依赖于这种能力。当继承被恰当使用时,所有从抽象类导出的类将共享该抽象类的接口。这意味着子类仅仅添加或重定义操作,而没有隐藏父类的操作。这时,所有的子类都能响应抽象类接口中的请求,从而子类的类型都是抽象类的子类型。只根据抽象类中定义的接口来操纵对象有以下两个好处:1)客户无须知道他们使用对象的特定类型,只须对象有客户所期望的接口。2)客户无须知道他们使用的对象是用什么类来实现的,他们只须知道定义接口的抽象类。这将极大地减少子系统实现之间的相互依赖关系,也产生了可复用的面向对象设计的如下
16、原则:针对接口编程,而不是针对实现编程。针对接口编程,而不是针对实现编程。http:/ 咨询QQ:460190900 Java私塾跟我学系列JAVA篇 欢迎大家前来北京JAVA私塾报名学习 联系电话:13651249175 张老师 313 5 运用复用机制运用复用机制 理解对象、接口、类和继承之类的概念对大多数人来说并不难,问题的关键在于如何运用它们写出灵活的、可复用的软件。设计模式将告诉你怎样去做。5.1.继承和组合的比较继承和组合的比较 面向对象系统中功能复用的两种最常用技术是类继承和对象组合(object composition)。正如我们已解释过的,类继承允许你根据其他类的实现来定义一
17、个类的实现。这种通过生成子类的复用通常被称为白箱复用(white-box reuse)。术语“白箱”是相对可视性而言:在继承方式中,父类的内部细节对子类可见。对象组合是类继承之外的另一种复用选择。新的更复杂的功能可以通过组装或组合对象来获得。对象组合要求被组合的对象具有良好定义的接口。这种复用风格被称为黑箱复用(black-box reuse),因为对象的内部细节是不可见的。对象只以“黑箱”的形式出现。继承和组合各有优缺点。类继承是在编译时刻静态定义的,且可直接使用,因为程序设计语言直接支持类继承。类继承可以较方便地改变被复用的实现。当一个子类重定义一些而不是全部操作时,它也能影响它所继承的操
18、作,只要在这些操作中调用了被重定义的操作。但是类继承也有一些不足之处。首先,因为继承在编译时刻就定义了,所以无法在运行时刻改变从父类继承的实现。更糟的是,父类通常至少定义了部分子类的具体表示。因为继承对子类揭示了其父类的实现细节,所以继承常被认为“破坏了封装性”。子类中的实现与它的父类有如此紧密的依赖关系,以至于父类实现中的任何变化必然会导致子类发生变化。当你需要复用子类时,实现上的依赖性就会产生一些问题。如果继承下来的实现不适合解决新的问题,则父类必须重写或被其他更适合的类替换。这种依赖关系限制了灵活性并最终限制了复用性。一个可用的解决方法就是只继承抽象类,因为抽象类通常提供较少的实现。对象
19、组合是通过获得对其他对象的引用而在运行时刻动态定义的。组合要求对象遵守彼此的接口约定,进而要求更仔细地定义接口,而这些接口并不妨碍你将一个对象和其他对象一起使用。这还会产生良好的结果:因为对象只能通过接口访问,所以我们并不破坏封装性;只要类型一致,运行时刻还可以用一个对象来替代另一个对象;更进一步,因为对象的实现是基于接口写的,所以实现上存在较少的依赖关系。对象组合对系统设计还有另一个作用,即优先使用对象组合有助于你保持每个类被封装,并被集中在单个任务上。这样类和类继承层次会保持较小规模,并且不太可能增长为不可控制的庞然大物。另一方面,基于对象组合的设计会有更多的对象(而有较少的类),且系统的
20、行为将依赖于对象间的关系而不是被定义在某个类中。这导出了我们的面向对象设计的第二个原则:优先使用对象组合,而不是类继承。优先使用对象组合,而不是类继承。理想情况下,你不应为获得复用而去创建新的构件。你应该能够只使用对象组合技术,通过组装已有的构件就能获得你需要的功能。但是事实很少如此,因为可用构件的集合实际上并不足够丰富。使用继承的复用使得创建新的构件要比组装旧的构件来得容易。这样,继承和对象组合常一起使用。然而,经验表明:设计者往往过度使用了继承这种复用技术。但依赖于对象组合技术的设计却有更好的复用性(或更简单)。你将会看到设计模式中一再使用对象组合技术。5.2.委托委托 委托(d e l
21、e g a t i o n)是一种组合方法,它使组合具有与继承同样的复用能力。在委托方式下,有两个对象参与处理一个请求,接受请求的对象将操作委托给它的代理者(d e l e g a t e)。这类似于子类将请求交给它的父类处理。使用继承时,被继承的操作总能引用接受请求的对象,C+http:/ 咨询QQ:460190900 Java私塾跟我学系列JAVA篇 欢迎大家前来北京JAVA私塾报名学习 联系电话:13651249175 张老师 314+中通过t h i s成员变量,S m a l l t a l k中则通过s e l f。委托方式为了得到同样的效果,接受请求的对象将自己传给被委托者(代理
22、人),使被委托的操作可以引用接受请求的对象。举例来说,我们可以在窗口类中保存一个矩形类的实例变量来代理矩形类的特定操作,这样窗口类可以复用矩形类的操作,而不必像继承时那样定义成矩形类的子类。也就是说,一个窗口拥有一个矩形,而不是一个窗口就是一个矩形。窗口现在必须显式的将请求转发给它的矩形实例,而不是像以前它必须继承矩形的操作。委托的主要优点在于它便于运行时刻组合对象操作以及改变这些操作的组合方式。假定矩形对象和圆对象有相同的类型,我们只需简单的用圆对象替换矩形对象,则得到的窗口就是圆形的。委托与那些通过对象组合以取得软件灵活性的技术一样,具有如下不足之处:动态的、高度参数化的软件比静态软件更难
23、于理解。还有运行低效问题,不过从长远来看人的低效才是更主要的。只有当委托使设计比较简单而不是更复杂时,它才是好的选择。要给出一个能确切告诉你什么时候可以使用委托的规则是很困难的。因为委托可以得到的效率是与上下文有关的,并且还依赖于你的经验。委托最适用于符合特定程式的情形,即标准模式的情形。委托是对象组合的特例。它告诉你对象组合作为一个代码复用机制可以替代继承。5.3.继承和参数化类型的比较继承和参数化类型的比较 另一种功能复用技术(并非严格的面向对象技术)是参数化类型(parameterized type),也就是类属(generic)(Ada、Eiffel)或模板(templates)(C+
24、)。它允许你在定义一个类型时并不指定该类型所用到的其他所有类型。未经指定的类型在使用时以参数形式提供。例如,一个列表类能够以它所包含元素的类型来进行参数化。如果你想声明一个Integer列表,只需将Integer类型作为列表参数化类型的参数值;声明一个String列表,只需提供String类型作为参数值。语言的实现将会为各种元素类型创建相应的列表类模板的定制版本。参数化类型给我们提供除了类继承和对象组合外的第三种方法来组合面向对象系统中的行为。许多设计可以使用这三种技术中的任何一种来实现。实现一个以元素比较操作为可变元的排序例程,可有如下方法:1)通过子类实现该操作(Template Meth
25、od的一个应用)。2)实现为传给排序例程的对象的职责(S t r a t e g y(5.9)。3)作为C+模板或A d a类属的参数,以指定元素比较操作的名称。这些技术存在着极大的不同之处。对象组合技术允许你在运行时刻改变被组合的行为,但是它存在间接性,比较低效。继承允许你提供操作的缺省实现,并通过子类重定义这些操作。参数化类型允许你改变类所用到的类型。但是继承和参数化类型都不能在运行时刻改变。哪一种方法最佳,取决于你设计和实现的约束条件。5.4 设计应支持变化设计应支持变化 获得最大限度复用的关键在于对新需求和已有需求发生变化时的预见性,要求你的系统设计要能够相应地改进。为了设计适应这种变
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 常用 设计 模式 java 程序
限制150内