Java设计模式101.doc_第1页
Java设计模式101.doc_第2页
Java设计模式101.doc_第3页
Java设计模式101.doc_第4页
Java设计模式101.doc_第5页
已阅读5页,还剩11页未读 继续免费阅读

下载本文档

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

文档简介

Java设计模式101一、 设计模式概述1、设计模式的简史设计模式第一次是由架构设计师 Christopher Alexander 在他所著的 A Pattern Language: Towns, Buildings, Construction(Oxford University Press,1977)一书中提到的。他引入了这一概念,并称为模式 对于反复出现设计问题的抽象解决方案 这一概念吸引了其它领域中一些研究人员的注意,特别是二十世纪八十年代中后期,那些开发面向对象的软件人员。对软件设计模式的研究造就了一本可能是面向对象设计方面最有影响的书籍:Design Patterns: Elements of Reusable Object-Oriented Software(即后述设计模式一书),由 Erich Gamma、Richard Helm、Ralph Johnson 和 John Vlissides 合著(Addison-Wesley,1995;请参阅参考资料)。这几位作者常被称为“四人组(Gang of Four)”,而这本书也就被称为“四人组(或 GoF)”书。在设计模式这本书的最大部分是一个目录,该目录列举并描述了 23 种设计模式。另外,近来这一清单又增加了一些类别,最重要的是使涵盖范围扩展到更具体的问题类型。例如,Mark Grand 在 Patterns in Java: A Catalog of Reusable Design Patterns Illustrated with UML(即后述模式 Java 版一书)中增加了解决涉及诸如并发等问题的模式,而由 Deepak Alur、John Crupi 和 Dan Malks 合著的 Core J2EE Patterns: Best Practices and Design Strategies 一书中主要关注使用 Java 2 企业技术的多层应用程序上的模式。有一个活跃的模式社区,它收集一些新模式,继续研究原有模式,并且领导大家推广模式。尤其值得一提的是,Hillside Group 主办了许多会议,其中包括在专家的指导下向初学者介绍模式。提供了有关模式和模式社区方面的信息的其它来源。2、模式的组成部分“四人组”将模式描述为“在一定的环境中解决某一问题的方案”。这三个事物 问题、解决方案和环境 是模式的基本要素。给模式一个名称,考虑使用模式将产生的结果和提供一个或多个示例,对于说明模式也都是有用的。不同的编目员使用不同的模板来说明它们的模式。不同的编目员对于模式的各个不同部分还使用不同的名称。每个类别对于每个模式的详细程度和分析级别上也有所不同。下面几页描述了设计模式和模式 Java 版中所使用的一些模板。3、设计模式模板设计模式使用下列模板: l 模式名称和分类:模式的概念性句柄和类别l 意图(Intent):模式解决什么样的问题?l 别名:模式的其它常见名称l 动机:阐明问题的方案l 适用性:在什么情况下使用模式?l 结构:使用“对象建模技术(Object Modeling Technique,OMT)”的图l 参与者:设计中的类和对象l 协作:设计中的类和对象如何协作l 结果:模式实现了哪些目标?它又失去了什么?l 实现:要考虑的实现细节、特定语言问题l 样本代码:用 Smalltalk 和 C+ 语言编写的样本代码l 已知应用:现实世界中的示例l 相关模式:对相关模式的比较和讨论 4、模式Java版模板模式 Java 版使用下列模板: 模式名称:模式的名称和对模式进行第一次描述时的引用 提要(Synopsis):模式的简短描述 环境:对模式要解决的问题的描述 推动力:促使解决方案形成所需考虑事项的描述 解决方案:一般解决方案的描述 结果:使用模式的结论 实现:要考虑的实现细节 Java API 用法:当 Java API 可用时,是指 Java API 的示例 代码示例:用 Java 语言编写的代码示例 相关模式:一组相关模式 5、学习模式首先要学习的最重要内容是每个模式的意图和环境:这个模式在什么情况下要解决什么问题。本教程只讲述一些最重要的模式,接下来,对于那些勤奋的开发人员,建议浏览一些类别并挑出关于每个模式的信息。在设计模式中,要阅读的相关章节是“意图”、“动机”和“适用性”。在模式 Java 版中,相关章节是“提要”、“环境”和“推动力与解决方案”。进行背景研究可以帮助您确定一种模式,这种模式能提供所面临的设计问题的一种解决方案。然后,在详细考虑这个解决方案和它的结果之后,针对适用性,进一步评估这个候选模式。如果不行,可以看看相关模式。在某些情况下,可能会发现可以有效地使用多个模式。而在另一些情况下,可能没有合适的模式,或者在性能或复杂性方面,使用合适的模式可能成本过高,而特定的解决方案可能是最好的办法。(也许这一解决方案还会造就一个尚未记录在案的新模式呢!)6、使用模式来获得经验在设计面向对象的软件中,关键步骤是发现对象。这里有许多技术可以帮助发现对象,例如:用例(use case)、协作图(collaboration diagram)或“类-职责-协作(Class-Responsibility-Collaboration,CRC)”卡,但是发现对象对于经验匮乏的设计人员来说是最困难的一步。缺少经验或指导会导致过多的对象,而这些对象存在过多的交互及由此产生的相关性,对于所创建的整体式系统,很难维护而且不可能重用。这违背了面向对象设计的初衷。设计模式帮助克服这类问题,因为它们传授从专家的经验中提炼出来的教训:模式文档专门技术。而且,模式不仅描述如何构造软件,更重要的是,还描述了类和对象如何交互(特别是在运行时)。明确地考虑这些交互及其结果会带来更灵活、可重用的软件。7、何时不使用模式在正确使用模式产生可重用代码的同时,其结果除了好处,还常常增加一定的成本。通常,通过引入封装或间接来得到可重用性,但封装和间接会降低性能和增加复杂性。例如,您可以使用 Facade 模式,用单个类将多个松散相关的类包装起来,以创建一套易于使用的功能。一个可能的应用程序可以是创建 Java“国际化 API”的外观。该方法对于独立的应用程序可能是适合的,因为应用程序中的各部分都需要从资源束、格式化日期和时间等获得文本。但是,对于将表示逻辑与业务逻辑分开的多层企业应用程序来说,这可能并不适合。如果将对“国际化 API”的所有调用都隔离在一个表示模块中 可能通过将它们包装为 JSP 定制标记来实现 再多一个间接层可能是多余的。在并发模式(关于单线程执行模式的结果)中讨论了另外一个何时应该谨慎使用模式的示例。随着系统的完善、经验的丰富或软件中瑕疵的暴露,偶尔重新考虑您以前所做的选择是有益的。您可能必须重新编写特定的代码以便它使用一种模式,或从一个模式更改到另一个模式,或除去整个模式以消除间接层。要允许更改(或至少要对此有所准备),因为这是不可避免的。二、 UML类图简介1、 类图UML 已成为面向对象设计的标准图形化工具。在 UML 定义的各种图中,本教程只涉及类图。在类图中,类被描绘为带有三层的盒子。顶层包含类名;如果类是抽象的,其名称用斜体表示。中间层包含类的属性(attribute)(也称为特性(property)或变量)。底层包含类的方法(也称为操作)。与类名相似,如果方法是抽象的,则它的名称用斜体表示。根据所希望的详细程度,可能省略特性,而只显示类名及其方法,也可以忽略特性和方法,而只显示类名。当在说明整个概念性关系时,常用这种方法。2、 类之间的关联通过在类之间画一条线来描绘它们之间的任何交互。一条简单的线表示一个关联,这通常是任何未指明类型的概念性关联。可以改变连线,以提供关于关联的更明确的信息。在线上添加一个开放式箭头来表示导航性(navigability)。添加一个三角形箭头表示具体化( specialization)或子类化。还可以在每端添加基数(或用星号表示未指明有多少个)来表示关系,如一对一和多对一的关系。下列各图显示了不同类型的关联:参考资料提供了有关 UML 和 Java 语言关联的更多资料。三、 创建型模式1、 概述创建型模式(creational pattern)规定了创建对象的方式。在必须决定实例化某个类时,使用这些模式。通常,由抽象超类封装实例化类的细节,这些细节包括这些类确切是什么,以及如何及何时创建这些类。对客户机类来讲,这些类的细节是隐藏的。客户机类只知道抽象类或抽象类实现的接口。客户机类通常并不知道具体类的确切类型。例如,Singleton 模式用来封装对象的创建,以便维护对它的控制。这不仅确保只创建一个实例,还允许延迟实例化(lazy instantiation);即,可以延迟对象的实例化,直到实际需要实例化时。如果构造器需要执行一个代价较高的操作(如访问远程数据库),这一点特别有用。2、 Singleton模式这段代码演示了如何使用 Singleton 模式来创建一个计数器,从而提供唯一的序列号,例如,可能需要用此序列号来作为数据库中的主键。/ Sequence.javapublic class Sequence private static Sequence instance; private static int counter; private Sequence() counter = 0; / May be necessary to obtain / starting value elsewhere. public static synchronized Sequence getInstance() if(instance=null) / Lazy instantiation instance = new Sequence(); return instance; public static synchronized int getNext() return +counter; 关于这个实现有几点要注意: Synchronized 方法用来确保类是线程安全(thread-safe)的。这个类不可以再子类化,因为构造器是 private。这可能是件好事,也可能不是,取决于正在保护的资源。要允许子类化,应该将构造器的可见性改为 protected。对象序列化可能会造成问题;如果 Singleton 被序列化,然后多次逆序列化,则会有多个对象,而不是一个。3、 Factory Method模式除了 Singleton 模式外,创建型模式的另一个常用示例是 Factory Method。在运行时必须决定要实例化几个兼容类中的哪一个时,使用这种模式。该模式的使用贯穿于 Java API 中。例如,抽象类 Collator 的 getInstance() 方法返回根据 java.util.Locale.getDefault() 确定的适用于缺省语言环境的整理对象:Collator defaultCollator = getInstance();返回的具体类实际上总是 Collator 的子类 RuleBasedCollator,但这是一个并不重要的实现细节。使用该类所需的只是抽象类 Collator 定义的接口。四、 结构型模式1、 概述结构型模式(Structural pattern)规定了如何组织类和对象。这些模式涉及类如何相互继承或如何从其它类组合。常用的结构型模式包括 Adapter、Proxy 和 Decorator 模式。因为这些模式在客户机类与其要使用的类之间引入了一个间接层,所以它们是类似的。但是,它们的意图有所不同。Adapter 使用这种间接修改类的接口以方便客户机类使用它。Decorator 使用这种间接向类添加行为,而不会过度地影响客户机类。Proxy 使用这种间接透明地提供另一个类的替身。2、 Adapter模式通常,Adapter 模式用来允许重用与客户机类希望看到的类相似的但又不完全相同的类。这种情况一般发生在:原始类能够支持客户机类需要的行为,但没有客户机类希望的接口,而且改变原始类是不可能的,或是不切实际的。或许,是无法获得源代码,或者其它地方正在使用它,并且不适合更改接口。这里有一个示例,它包装了 OldClass,使客户机类可以使用 NewInterface 中定义的 NewMethod() 方法来调用 oldclass: public class OldClassAdapter implements NewInterface private OldClass ref; public OldClassAdapter(OldClass oc) ref = oc; public void NewMethod() ref.OldMethod(); 3、 Proxy和Decorator模式Proxy 是另一个类的直接替身,它通常与所替代的那个类有相同的接口,因为它实现一个公共接口或抽象类。客户机对象并不知道它正在使用代理。当客户机希望使用某个类,而访问该类的方式很明显必须用间接的方式时(例如,因为客户机需要受限访问或它是一个远程进程),应该使用 Proxy 模式。与 Proxy 相似,Decorator 也是另一个类的替身,通常因为它是一个子类,所以它也与所替代的那个类有相同的接口。但是,意图不同。Decorator 模式的目的是用对客户机类透明的方式来扩展原始类的功能。Java API 中 Decorator 模式的示例可在用于处理输入和输出流的类中找到。例如,BufferedReader() 使得从文件中读取文本更方便更有效:BufferedReader in = new BufferedReader(new FileReader(file.txt);4、 Composite模式Composite 模式规定复杂对象的递归组合。其意图是以一种一致的方式处理所有的组成对象。参与这一模式的所有对象,不管是简单还是复杂的,都是从定义公共行为的一个公共抽象组件类派生而来的。用这种方法将各种关系强制转换成部分-整体的层次结构,从而使系统(或客户机子系统)需要管理的对象类型变得最小。例如,画图程序的客户机以它要求其它对象(包括组合对象)的相同方式要求线条画出自身。五、 行为模式1、 概述行为模式(Behavioral pattern)规定了对象之间交互的方式。它们通过指定对象的职责和对象相互通信的方式,使得复杂的行为易于管理。2、 Observer模式Observer 是一个很常见的模式。在您用“模型视图控制器(Model/View/Controller)”体系结构实现应用程序时,通常会使用这一模式。该设计的“模型视图”部分是为了去除数据的表示与数据本身的耦合性。例如,设想这种情况:数据保存在数据库中,可以以多种格式(表格或图形)显示该数据。Observer 模式建议显示类向负责维护数据的类注册它们自身,这样在数据发生更改时可以通知显示类,从而它们可以更新它们的显示。Java API 在它的 AWT/Swing 类的事件模型中使用该模式。它也提供了直接支持,这样出于其它目的时也能实现该模式。Java API 提供了 Observable 类,它可以由要观察的对象进行子类化。Observable 提供了以下方法:Observable 对象调用 addObserver(Observer o) 来注册自己。setChanged() 将 Observable 对象标记为已更改。hasChanged() 测试 Observable 对象是否已更改。根据 hasChanged(),如果 Observable 对象已更改,notifyObservers() 通知所有观察类。 与此相应,还提供了一个 Observer 接口,它包含一个由 Observable 对象在其发生更改时调用的方法(当然,是在 Observer 已向 Observable 类注册了它自己的前提下):public void update(Observable o, Object arg)下面示例演示了如何使用 Observer 模式来通知诸如温度等传感器的显示类已检测到变化:import java.util.*;class Sensor extends Observable private int temp = 68; void takeReading() double d; d =Math.random(); if(d0.75) temp+; setChanged(); else if (d0.25) temp-; setChanged(); System.out.print(Temp: + temp + ); public int getReading() return temp; public class Display implements Observer public void update(Observable o, Object arg) System.out.print(New Temp: + (Sensor) o).getReading(); public static void main(String ac) Sensor sensor = new Sensor(); Display display = new Display(); / register observer with observable class sensor.addObserver(display); / Simulate measuring temp over time for(int i=0; i 20; i+) sensor.takeReading(); sensor.notifyObservers(); System.out.println(); 3、 Strategy和Template模式Strategy 和 Template 模式是类似的,因为它们都允许对固定的一组行为使用不同的实现。但是,它们的意图有所不同。Strategy 用来允许在运行时动态地选择算法或操作的不同实现。通常,在抽象类中实现任何公共行为,而具体子类提供那些有差异的行为。客户机一般知道可用的不同策略,并且可以在其中选择。例如,抽象类 Sensor 可以定义测量,并需要具体子类实现不同的技术:一个可能提供连续的平均值,一个可能提供瞬时测量, 而另一个可能取某段时间内的峰值(或最低值)。Template 模式的意图不是象 Strategy 中那样允许以不同的方法实现行为,而是确保实现确定的行为。换句话说,Strategy 关注的是允许多样化,而 Template 关注的是加强一致性。Template 模式是作为抽象类来实现的,它常用来为具体子类提供蓝图或轮廓。有时,用它来实现系统中的挂接(hook),如应用程序框架。 六、 并发模式1、 概述并发模式(Concurrency pattern)规定协调或顺序对共享资源访问的方式。到目前为止,最常用的并发模式是单线程执行(Single Thread Execution),它必须确保一次只有一个线程有权访问某个代码段。这段代码称为临界段(critical section),通常它是获取对必须共享的资源的访问权的一段代码(如打开端口),或是应为原子性的一系列操作,如获取一个值,执行计算,然后更新该值

温馨提示

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

评论

0/150

提交评论