《23种设计模式详解 (2).ppt》由会员分享,可在线阅读,更多相关《23种设计模式详解 (2).ppt(80页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、设计模式详解何谓设计模式 在面向对象程序设计(OOP)过程中,我们经常会遇到很多重复出现的问题,总结解决这些问题的成功经验和最佳实践便形成了设计模式(Design Pattern)。其核心思想是将可重用的解决方案总结出来,并分门别类。从而指导设计,减少代码重复和优化体系结构。采用设计模式的益处重用,避免代码重复冗余优化体系结构提升系统的可维护性和弹性代码更加容易测试,利于测试驱动为性能优化提供便利使软件质量更加有保证增强代码可读性,便于团队交流有助于整体提升团队水平设计模式、重构和Antiparttern设计模式是成功经验和最佳实践的总结,指导设计人员采用正确精良的设计。重构(Refactor
2、)专注于软件的渐进完善。通过消除重复冗余代码,并将存在体系结构缺陷的代码重新构建成符合设计模式的代码来达到设计精良软件的目的。Antiparttern与设计模式相反,是失败教训的总结。其澄清了许多设计中经常面临的陷阱和容易混淆的问题,能有效防止开发人员犯错误,从而做出正确选择。设计模式与UML 设计模式是OOP的方法论,其内容描述基本是围绕对象的结构和协作关系设计。因此需要一种直观的模型将上述内容清晰地表示出来。统一建模语言(UML)是OOP的建模语言,其核心就是把软件的设计思想通过建模的方法表达出来。故非常适合于表达设计模式。同时UML已经被广泛用于软件设计,这也推动了设计模式的应用。设计模
3、式分类Creational patterns 帮助我们更好地组织创建对象的代码。增强弹性,以应付在不同情况下创建和初始化对象的代码变更。Structural patterns 增强代码重用,优化对象结构,使其职责分明、粒度合适,以松耦合的体系结构来减低代码的rippling效应。Behavioral patterns 更好地定义对象间的协作关系,使复杂的程序流程变得清晰。Creational PatternsThe Factory PatternThe Abstract Factory PatternThe Singleton PatternThe Prototype PatternThe F
4、actory Pattern Factory是最常见的设计模式之一,可帮助我们组织创建对象的代码,通常用于以下两种情况:v 创建复杂的对象,并进行初始化。v 根据不同的环境(输入参数),创建不同用途的对象。一般这些对象都是实现了相同的接口或继承于同一基类。Factory模式的JDBC应用OracleDataSource负责创建链接,由函数getConnection获取链接Factory模式应用于DAO XMLDB是XML数据库访问接口,针对Oracle和DB2分别提供了实现。XMLDB_DAOFactory为类工厂,根据输入的参数dbtype,创建不同的XMLDB实现类。更多的Factory模
5、式应用例子 Hibernate的SessionFactory,将数据库表和对象的映射关系写入XML格式的配置文件,然后由SessionFactory根据它来创建Session。EJB容器本身就是一个EJB的Factory。当客户端调用EJB的时候,由容器创建EJB供其使用。The Abstract Factory Pattern 在介绍Abstract Factory之前,先回顾下Factory模式的JDBC应用。由于很多系统需要访问不同的数据库,故在得到Connection之前要获取不同的DataSource。于是我们又遇到了Factory模式所要解决的问题:创建一个Factory来获取不同
6、的DataSource。而DataSource本身又是一个Factory。由上述我们不难引出Abstract Factory的定义,就是用于创建Factory的Factory。其设计思想和Factory的完全一致,不过是一种特殊的Factory而已。Abstract Factory的EJB应用 EJB容器需要支持多种数据库,每种不同的数据库有相应的DataSource。因此容器先根据部署文件里面的设置,创建各个DataSource,然后绑定到其目录服务中。使用DataSource的时候只要从目录服务中获取即可,故其充当了DataSource的Abstract Factory。实际上,EJB容器
7、将所有资源(JMS Factory、EJB Home等)的Factory全绑定到了目录服务中,使用这些Factory的时候都是由目录服务获取,因此目录服务是所有资源Factory的Abstract Factory。The Singleton Pattern Singleton模式应用在系统中的某些对象有且只能有一个实例的情况下,也就是确保类只能实例化一次。很多类都是Singleton,例如Java语言里的System、Runtime和Math类,JDBC中的DriverManager等。Singleton模式的实现利用Static Classes来实现。如Java语言中的System和Math
8、类。结合Factory模式实现。由于Factory负责对象的创建,在其中实现Singleton更优雅且具弹性。此外,因多数Factory都要求只有一个实例,Abstract Factory的实现广泛采用了Singleton模式。The Prototype Pattern 当创建对象非常耗费资源且复杂的时候,为避免重复对象的创建过程,而采用复制已有对象的副本(或重用已有对象)再作适当更改的方法来加快其创建速度。这便是Prototype模式。J2EE环境中,多数昂贵资源的创建都通过采用实例缓冲技术来实现Prototype模式。典型例子为JDBC的链接缓冲池。Prototype模式的应用 Proto
9、type模式对于昂贵的资源来说是非常有价值的,在J2EE环境里面得到广泛的应用。其实现多数是以实例缓冲的形式出现,且有不少开源项目专注与相关类库的开发。与Singleton模式类似,Prototype模式多数是结合Factory使用。如容器中的DataSource就具备链接缓冲的功能。小节Factory模式用于屏蔽对象的创建逻辑,根据输入的数据从相似的类中选择和返回相应类的实例。Abstract Factory模式是用于产生Factory的Factory。Singleton模式可确保系统中的某些类有且只有一个实例,并使其能全局访问。Prototype模式运用在创建新对象代价过高的环境下,通过重
10、用已有对象达到节省资源和提高性能的目的。Structural PatternsThe Adapter PatternThe Composite PatternThe Decorator PatternThe Facade PatternThe Proxy PatternThe Adapter Pattern Adapter模式用于转换类的编程接口,将编程接口不同而功能相似的类用一个统一的接口封装起来。顾名思义,Adapter就是起到一个中转桥梁的作用。其思想也很简单,编写一个实现了统一接口的类,由其与编程接口相异的类打交道,从而达到屏蔽类编程细节的目的。Adapter模式的实现Adapter模
11、式的实现方案通常有两种:类继承 以需要适配的类为基础,派生一个子类,然后在子类中添加新的函数,实现制订的统一接口。类联合 创建一个新的类,其中包含需要适配的类。然后给新类添加函数,实现制订的统一接口。Adapter模式实现和应用举例举一个简单的例子来说明Adapter的应用和实现。下面看到的是一个简单的Java程序,将左边列表中的字符串移到右边,或者反之。开始程序是用AWT类库实现的,而后来我们要将其改为JFC,因两个类库的功能类似,但是调用接口差异大,所以引入Adapter模式,避免变更波及整个程序。示例附图函数变更AWT List classadd(String)remove(String
12、)String getSelectedItems()JFC JList classObject getSelectedValues()The Composite Pattern编程中往往会遇到一个组件既可仅为一个单独的对象,也可用对象集合来表示的情况。这便是Composite模式的用武之地。典型的案例是树型结构数据,每个节点既可包含多个子节点,也可能是叶子节点。且各个节点一般是不同的类。为了将所有节点组织起来,从所有节点类中抽象出能表示其共性和树型结构的接口,这便是Composite。Composite模式举例 以上为公司所有职位的结构图,每个员工可能有其下属,也包含了姓名和工资等共有的信息。
13、如何将类组织起来,使其既能表达树型结构的组织关系,又可以表示出员工的共有信息,是Composite模式要解决的问题。Composite模式示例的实现综合树型结构表示所需函数以及员工的共有信息可以提取出以下抽象类(或接口):public abstract class Employee public float getSalary().public String getName().public float getSalaries().public abstract int getTypeCode();public abstract boolean isLeaf();public boolean
14、add(Employee e).public void remove(Employee e).public Employee getChild(String s).public Enumeration elements().抽象类Employee的add、remove、getChild和elements体现了树型数据结构的基本操作,其它的属性为员工的共有信息。然后以之为基类,根据员工的职能派生出具体的实现类。Composite模式应用于DOMXML数据同样也可看成是树型结构,因此XML解释器将其由字符串转换成一种树型模型DOM。然后就可以基于DOM对XML进行数据提取、遍历及各种编辑操作。DO
15、M是W3C制订的标准,完全基于Composite模式。其中所有节点都用Node接口表示,然后由其派生出Element,Text和Attribute等接口。DOM应用图例public interface Node public String getNodeName();public short getNodeType();public String getPrefix();.public Node getParentNode();public boolean hasChildNodes();public NodeList getChildNodes();public Node appendChi
16、ld(Node newChild);public Node removeChild(Node oldChild);public Node insertBefore(Node newChild,Node refChild);.The Decorator PatternDecorator模式为我们提供了一种无需创建派生类就能改变对象行为的方法。某个对象需要改变行为,添加附加的特性,多数情况下采用类继承是能够解决。比如当其需要三种不同的附加特性,可以为其创建三个派生类。但是若它还需要同时具有其中两种特性或者是各种特性的任意组合的时候,类继承的方法就不再适合了,Decorator模式则为解决之道。De
17、corator模式的实现使用类继承解决对象行为改变问题时,关键是在派生类中覆盖需要改变行为的函数。这实际上是一种拦截函数激发的方法,在函数激发前(或后)添加新的动作而实现行为变更。截获函数激发还可先将欲拦截的函数提取到一个基类或接口中。再针对各种动作分别实现相应的类。然后通过类的联合嵌套就能实现函数的拦截。且该方法能由改变类的嵌套来达到以任何特性的组合改变函数行为的目的。这便是Decorator模式实现方案。本质上看,这是一种关于函数拦截的设计模式。Decorator模式用于Java的I/OJava的I/O系统是完全构建在Decorator模式之上的。其使用方法和我们前面介绍的例子是非常相似的
18、。实现方面则比示例要复杂些,接口和抽象类都用上了。借助Decorator模式,Java的I/O系统非常灵活,且扩展性佳。Decorator模式用于ServletServlet是用于编写动态网页的服务端组件。容器接收到Http请求后就激活相应的Servlet,由其运行后输出结果返回给客户端。在Servlet激发之前(或后)往往需要执行些附加的动作,比如显示广告、网页的一些固定标题栏等等。于是依据Decorator模式,引入了Filter。The Facade Pattern通常随着代码的增加,系统变得越来越复杂,演化出多个模块,甚至加入层式设计。特别是引入设计模式后,类的数目开始膨胀。这些都会导
19、致程序的逻辑过于复杂难懂。Faade模式提倡将复杂系统依据其各模块(或层)的功能,提取出接口,屏蔽掉具体的实现逻辑,使相互间的调用明晰简洁。这既确保了模块间的隔离性,促进模块保持职责明晰,也使系统的体系框架保持清晰。Faade模式与Factory模式Faade模式用于屏蔽模块的具体实现,Factory模式则是侧重于屏蔽创建逻辑。这两个模式综合起来后就能使得模块间做到完全隔离。两者结合的例子非常多,在所有的Java技术规范中都有很好的体现。Faade模式在J2EE中的应用J2EE程序设计中,往往采用层式结构,一般分成Web、Service、Domain和Persistence,共四个层。层与层之
20、间的调用遵照Faade模式,完全依靠接口。若是违反该原则,会造成很多不良影响。特别是涉及到远程通讯和事务的问题时,后果通常非常严重。The Proxy Pattern当需要用简单的对象来表示一个复杂对象的时候,Proxy模式便可以派上用场。若是创建对象比较耗时或消耗资源很多,则可以为其创建一个Proxy对象,将对象的创建和初始化推迟到真正需要使用其的时候进行。这也是通常所说的惰性载入策略。此外,如对象访问涉及权限问题,也可采用Proxy模式。Proxy模式的应用 EJB是典型的分布式组件,其客户端全都是通过Proxy对象与之交互的。这样容器可以从中透明地加入安全、事务、惰性载入和生存期管理等服
21、务。JDO使得客户端能以对象的方式操作数据库的数据。实际上,客户端访问的对象全是代理对象,其中实现了缓冲和惰性载入的功能。Proxy模式与Faade模式Proxy模式常常和分布式系统关联在一起,既然涉及物理上分离的系统,那么他们之间的交互调用要有一个定义良好的接口才行,这就是Facade模式所关注的问题。因此在引入Proxy模式时,往往必须先将接口进行精心设计,故连带使用了Facade模式。Behavioral PatternsChain of ResponsibilityThe Command Pattern The Interpreter PatternThe Iterator Patte
22、rnThe Mediator PatternThe Observer PatternThe State PatternThe Strategy PatternThe Template PatternThe Visitor PatternChain of ResponsibilityChain of Responsibility模式允许多个类处理一个相同的request,却无需相互知晓,从而为这些类提供了松耦合的结构。很多系统的request响应处理机制都使用了Chain of Responsibility模式,request沿着响应链传递,直至遇到能处理之的类,如JFC和MFC的消息处理、Se
23、rvlet的HTTP请求响应等。Chain of Responsibility的实现该模式的实现关键在于响应链的实现,即是将所有request的处理类串起来形成响应链。响应链的操作主要是添加处理类和激发处理类,用接口表示如下:public interface Chain public void addChain(Chain c);public void invoke(String mesg);所有的处理类都实现以上接口,即可组成响应链。程序能根据输入的字符串显示不同的内容。实现举例响应链为:SenderImagerColorImageFileListRestListChain of Respo
24、nsibility的应用Servlet用于动态响应HTTP请求,经常遇到将request传给多个Servlet的情况,故相关的设计广泛采用了该模式。典型例子就是Servlet的Filter,它是Decorator模式与Chain of Responsibility模式的结合体。The Command PatternCommand模式常用于根据不同request执行相应处理代码。其核心思想是将处理代码分别封装到不同的具有统一激活接口的类中。这样可借助数组或散列等对处理类进行管理和优化其激发过程,使request的传递与处理代码分离。且既可将各处理代码相互隔离,也使得响应端对客户端完全透明。Com
25、mand模式的应用非常广泛,J2EE和开源项目中经常可见其身影(Servlet、Struts、JUnit等),它也是Refactor所用到的基础模式之一。Command模式实现举例借用Chain of Responsibility模式中的例子,对其进行改造使其符合Command模式。由例子不难看出采用Command模式后,程序的代码减少,结构得到优化,弹性大大增强。同时也不难发现Command模式容易导致类数量的膨胀。Command模式与响应链Command模式和响应链都起到了隔离处理代码和使响应端对客户端透明的作用。Command模式简化和优化了request到处理代码的传递,为reques
26、t的扩展提供良好支持。响应链只是将传递流程以链式或树型结构管理起来,为处理代码的激发顺序提供了很好的灵活性。Command模式的应用举例Servlet是完全遵照Command模式设计的。每个Servlet都包含两个激发函数doGet和doPost。激活Servlet的URL或Map则在部署文件里设定。JUnit也是以Command模式为基础的。TestCase需要通过TestSuit以树型的结构组织起来。这样就必须将所有TestCase设计成具有统一激活接口的类。The Interpreter Pattern某些系统得益于具备专门的语言来描述其所能进行的操作,这便是Interpreter 模式
27、的用武之地。定制语言我们经常会接触到,如VBA、SQL等。解释器的设计可能非常复杂,要求设计人员具备相关的技能。故描述何时应引入定制语言是Interpreter模式的关键之一。何时引入定制语言程序必须解释执行任意的字符指令 程序以字符指令为输入,根据指令执行不同的动作。例如数学运算和数理统计方面的软件、数据库的DDL等。程序必须产生多种多样的输出结果 尽管这些输出结果和执行流程各异,但它们执行所包含的操作步骤却是相同的。故需要一种语言来描述相关的操作。如报表软件、数据库的DML、转换XML文档的XSL等。定制语言和XMLXML是一种元语言,可以基于其上构建不同的应用语言。由于XML是业界广为接
28、受的标准,基于其上的语言显得更加简明易懂。而且XML的解释器通用易得,XML的树型结构又能清晰地表示出语法树,故为解释器的实现提供了不少便利。不少系统的定制语言都采用之,如Ant、Cocoon、Struts、CQL、XQuery等The Iterator PatternIterator模式简单而常用,它允许我们通过标准的接口遍历某个集合中的数据而无需关心其内部的数据组织结构。此外,还可以定制特殊的Iterator来过滤返回的数据。在很多涉及数据遍历的场合中都会用到Iterator,如Java的链表、散列等数据集合的遍历,数据库查询返回的数据集遍历。Iterator模式的接口定义Iterator
29、的接口定义大同小异,可以根据具体的情况定制。通常情况下,接口定义如下:public interface Iterator public Object First();public Object Next();public boolean hasNext();public Object CurrentItem();Iterator和Composite模式Composite模式常用于组织树型结构数据,故同样会面临数据遍历的问题。树型数据的遍历主要有两种不同的算法:深度优先和广度优先。利用Iterator,可以将具体的遍历算法屏蔽,客户端也就不再受算法的困扰。此外,Iterator还可用于每个节点所
30、包含子节点的遍历。Iterator模式实现举例左边的列表是通过Iterator遍历所有数据并显示右边的列表则采用了包含过滤功能的Iterator,只列出属于某个俱乐部的队员。The Mediator pattern随着系统功能的增加,更多的类被引入,且相互之间的调用变得更加复杂频繁。类之间因调用需要知晓对方的函数,然而知道得越多,系统变得越难维护,松耦合的结构会逐渐被破坏。为保持系统的松耦合结构引入Mediator模式。Mediator是唯一包含类函数调用细节的类,其余所有类都是通过它来实现相互通信,从而隔离各个类,延续系统的松耦合结构。Mediator实现举例从左边列表选中的文本加入文本框中
31、,同时Copy按钮变为Enabled。点击Copy按钮,文本加入到右边列表,且Clear按钮Enabled。点击Clear后,文本框和右列表被清空,Copy和Clear按钮重新变成Disabled。示例中的组件调用关系从图中可见原先系统各组件存在着复杂的调用关系。采用Mediator模式后,涉及组件间功能调用的代码全部集中到了Mediator,故组件间的关系变得简明,系统保持了松耦合结构。Mediator、Factory和Facade系统通常采用分而治之的策略划分成多个模块。模块的结构设计主要面临三方面的问题:v 模块间的通信v 模块内各类的相互调用v 创建和初始化管理结合Mediator、F
32、actory和Faade,可设计出结构优雅规范的模块。The Observer Pattern在很多系统中都会遇到需要同时将数据以不同的形式显示出来,且显示要能及时反应出数据的变更。传统的做法经常将数据逻辑和表示逻辑混和在一起。随着数据表现形式的增加,系统会陷入烦杂而难以维护的境地。解决该问题需要引入Observer模式。将数据和表现形式彻底隔离,为表现形式的多样化提供最大的弹性。Observer模式的原理 Observer模式将数据逻辑(Subject)及其表现逻辑(Observers)完全分离,分别封装到不同的类中。当数据变更时会通知Observers刷新,用户只需通过Subject来操作
33、数据,Observers对其完全透明。因此添加新的Observers不会对其它部分有影响。Observer模式的实现由原理不难看出Observer模式的实现关键在于Subject和Observers间的协同工作。为了响应数据变更,Observers需要实现接口:abstract interface Observer public void sendNotify(数据变更);然后Observers将其注册到Subject,数据变换时由其调用接口的sendNotify通知Observers刷新。显然,Subject需要实现以下接口来接受注册。abstract interface Subject p
34、ublic void registerInterest(Observer obs);实现举例例子带有一个Subject(底下的窗口)和两个Observes(上面的两个窗口)。Subject中的选择改变时,Color窗口会变色,列表窗体则随之选中不同的项。Observer模式与MVC MVC(Model-View-Controller)的核心思想和Observer模式是完全类似的。数据模型(业务逻辑)和表现逻辑相互隔离,Controller则负责与客户交互,根据请求调用M和V的功能。通常情况下Controller并不单独存在,而是和M或V结合(JFC中便是如此)。但在分布式系统中,客户端不可能直
35、接与M或V进行交互,此时Controller将独立出来并发挥重要作用。访问协议、请求分发、安全认证、日志记录和异常处理等都由其承担。StrutsMVC的成功典范MVC在Web程序开发中获得广泛应用,由此也诞生了很多MVC的框架,其中的成功典范当属Struts。其工作流程如右图:Struts将重点放在Controller,实现了请求解释和数据校验、请求分发、声明型异常处理和页面跳转等特性。The State pattern复杂的程序往往有许多状态,不同状态下的行为相异。如何使得系统随着状态增加而仍然保持逻辑清晰是State模式所解决的问题。已往遇到该问题的时候通常都是使用大量的if-else或s
36、witch语句来判断应该采取何种行为。这种方法容易使系统陷入逻辑含糊不清的境地,State模式则可帮助系统以简洁的方式工作于不同状态。State模式举例讲解State模式原理之前先看一个类似画笔的绘图程序。窗口ToolBar的按钮分别对应功能:选择、画矩形、填充、画圆和清除。示例程序的设计思路程序设计的难题在于按下ToolBar的不同按钮时要采取相应的行为。但是不难发现状态不同的代码差异主要集中在窗体的mouseDown、mouseUp和mouseDrag事件的响应函数。由此可提出基类:public class State public void mouseDown(int x,int y)p
37、ublic void mouseUp(int x,int y)public void mouseDrag(int x,int y)然后针对不同的状态为该接口写子类,并创建StateManager管理之,负责状态的维护。这样窗体mouse事件的响应代码只需和StateManager打交道,与各状态的执行代码完全隔离。State模式的原理状态的差异通常只是引起程序某些方面的行为不同,故可以将存在差别的地方分别用函数概括总结出来,再把这些函数集中形成接口或者虚类。然后针对不同的状态来分别编写其实现,并创建StateManager来管理之。这样程序只需要通过StateManager来工作,将不同状态的
38、处理代码与之隔离开来,因此变得简洁易懂。系统的弹性和可维护性都得到很大提升。The Strategy Pattern 系统的某些操作存在多种算法的时候,如何将这些算法组织起来,保持代码的简明清晰是Strategy模式所解决的问题。Strategy模式的核心思想与State是类似的。将需要使用不同算法的各个部分用函数概括出来,集中提取成基类。然后就可以针对不同的算法写实现。同样还需Context类把这些类管理起来。Strategy模式实现举例读取数据,并以不同的算法将其显示出来Strategy模式与State模式两个模式很相似,核心思想是基本一致的,其差别主要源于各自的应用范围不同。v Stra
39、tegy的Context只是实例化指定的算法类。而State的StateManager初始化时会创建所有状态的处理类。v Strategy中封装的算法,从某个角度看都是在做相同的事情,而State的不同状态执行的是完全不同的操作。v State中会频繁出现状态切换跳转的情况,但是Strategy则不然。The Template Pattern 当我们创建一个基类,将其中某些方法留给子类实现,实际上就使用了Template模式。该模式的实现方法非常简单,只要定义基类(往往是虚类)再在子类中覆盖实现其父类某些函数即可。尽管Template模式的实现很简单,但是其思想是相当重要的,对代码重用和体系结
40、构优化有着重要意义。此外,它也是Refactor最常用的模式之一。Template模式的核心思想Template模式的核心思想包括两方面:v将程序的主体逻辑和策略在基类中实现,而某些方面的具体实现细节则留给子类。这样便能充分体现出策略与方法分离的思想,使系统更具弹性。v某些类彼此之间都具有一些共同的代码,为避免这些代码的重复,往往将其提取出来,放到一个基类中去。这是Template模式在Refactor中获得广泛应用的根本原因。Template模式举例以缓冲池的实现为例子演示Template模式如何体现策略和方法分离的思想。基类负责数据的存取和删除操作。子类分别实现了FIFO和LRU淘汰算法。
41、Template、State与StrategyTemplate模式用于处理策略与方法分离时使人自然想到State和Strategy。虽然都是针对不同的情况执行相应的代码,但是State和Strategy可动态地调整,而Template是静态的,不适合运行期动态变化的应用环境。另外,Template依靠类继承来实现,Java的单根继承特性有时会阻碍其运用,此时可改用State或者Strategy模式。Template模式应用举例 OSCache是一个高效的缓冲池实现,其核心采用Template模式设计。结构和示例中的完全相同,只是它的实现充分考虑到了多线程的并发访问。JUnit中的每个测试用例都
42、会包含初始化和释放资源的代码。因此基类TestCase包含了相关的虚函数由子类实现,这样系统在运行的时候就能执行这些代码。The Visitor Pattern顾名思义Visitor模式是用于解决数据访问的问题。当我们需要遍历某些对象,并对其中每个都执行一些的处理操作的时候,Visitor模式便能派上用场。Visitor在两种情况下特别有用,其一是欲访问的对象由不同类实现,编程接口不同,另外则是遍历对象时,遍历代码复杂而重复。Visitor模式的实现Visitor的实现主要是两个步骤:n创建Visitor类,在其中实现visit(*)函数。n所有被访问的对象都要实现函数public void
43、accept(Visitor v)v.visit(this);/call visitor method 遍历数据之前先创建Visitor,然后遍历的过程中调用每个类的accept函数Visitor模式应用举例Spring框架充分利用了Visitor的特性来简化JDBC编程,巧妙地实现了反控。JDBC操作时,除了数据处理,其它部分基本是相同的。因此采用Visitor模式,把数据处理逻辑封装到用户定义的Visitor中,而框架则负责初始化并执行SQL语句、遍历数据集合和释放资源。如此一来JDBC的编程的冗余代码得到彻底消除且实现了反控。Visitor和Iterator Visitor和Iterator都是用于数据遍历的,其差异主要是由所采取的数据读取模式不同而引起。Visitor使用的推模型,而Iterator用的则是拉模型。拉模型更加简单直观,但是推模型能充分利用OOP的多态来简化代码,优化体系结构。