??xml version="1.0" encoding="utf-8" standalone="yes"?> 6?数据讉K对象 数据讉K对象(data access objectQDAO)模式数据访问逻辑抽象为特D的资源Q也是说将pȝ资源的接口从其底层访问机制中隔离出来Q通过数据访问的调用打包Q数据访问对象可以促q对于不同数据库cd和模式的数据讉K?/P>
q种模式出现的背景在于数据访问的逻辑极大E度上取决于数据存储的格式,比如说关pd数据库、面向对象数据库、磁盘文件等?/P>
目前大部分的J2EE应用E序都需要在一定程度上使用可持久性的数据Q而实现持久性数据的Ҏ因应用程序不同而异Qƈ且访问不同存储格式数据的应用E序接口(API)也有着显著的差别;有的时候,应用E序q会讉K存储在不同操作^C的数据,q得问题更为复杂,通常Q应用程序会使用׃n的分布式lgQ如实体bean来表达持久性数据。应用程序可以用bean理的持久性实体beanQ而在实体bean中植人数据访问逻辑Q或者用容器管理的持久性实体beanQ从而容器理所有的事务和持久性细节;而如果应用程序对于数据访问的需求十分简单的话,也可以采用会话bean或Servlet直接讉K持久性存储来d和修Ҏ据?/P>
一些应用程序可以用JDBC应用E序接口来访问关pL据库中的数据QJDBC负责一般的持久性数据访问和理Q在J2EE应用E序中,JDBC中可以嵌入SQL语句Q用以访问关pd数据库,当然Ҏ数据库类型的不同QSQL语句的词法和语法也会有所不同Q需要说明的是,当数据存储格式不同的时候,数据讉K逻辑的区别就更加明显了,例如关系型数据库、面向对象数据库和磁盘文Ӟ各自数据的访问逻辑各有千秋Q这样一来就造成了程序代码和数据讉K代码之间的依赖关p;当程序组Ӟ卛_体bean、会话bean或servlet、JSP{需要访问数据源Ӟ它们会用正的应用E序接口来得到连接ƈ理数据源,但这样也会造成q些lg与数据源物理实现之间的依赖关p,从而得应用程序很难从一个数据存储实体移植到另一个数据存储实体中去;当数据源的物理实现变化的时候,应用E序也必ȝ应地加以改变?/P>
Z以上所讨论的问题,开发h员开始采用数据访问对象的Ҏ。数据访问对象实际上是包含对于所有数据访问逻辑的对象,q管理着对于数据源的q接Q根据数据源的不同,数据讉K对象实现了不同的讉K机制Q这里所说的数据源可以是持久性存储介质,如关pd数据库,也可以是外部服务Q如B2B的数据交换;不仅是用P而且包括应用pȝ中的其他lgQ也可以使用数据讉K对象所提供的数据访问接口,数据讉K对象数据源的物理实现细节与其用户完全分d来,q且在底层数据源变化的时候,数据讉K对象向用h供的接口是不会变化的Q这U方法应用pȝ使用数据讉K对象时可以适应多种数据存储介质QMQ数据访问对象就是系l组件和数据源中间的适配器?/P>
?中的cd表示了数据访问对象设计模式的参与对象和之间的调用关系Q图9是这U设计模式的序列图?/P>
? 数据讉K对象cd ? 数据讉K对象序列?/P>
对于?序列图中的组件加以解释如下: (1)业务对象(Business Object)。表C数据的用户Q它需要对于数据的讉KQ一个业务对象可以用会话bean、实体bean或是其他JavaE序来实现?/P>
(2)数据讉K对象(Data Access Object)。数据访问对象是q种模式中的主题Q它提供了底层数据访问的对象Qƈ其提供l业务对象以使得后者能够透明地访问数据源Q同时业务对象也数据的加蝲和存储操作移交给数据讉K对象处理?/P>
(3)数据?Data source)。这里指的是数据源的物理实现Q这个数据源可以是一个数据库Q包括关pd数据库、面向对象数据库或文件系l?/P>
(4)传输对象(Transfer Object)。这里的传输对象指的是数据蝲体。数据访问对象可以用传输对象来向用戯回数据,而数据访问对象同样可以从用户那里得到传输对象来对数据源中的数据进行更新?/P>
下面l出几种实现数据讉K对象设计模式的方法?nbsp; (1)自动数据讉K对象代码的生?/B> 既然每一个业务对象都对应于一个数据访问对象,那么开发h员就可以建立业务对象、数据访问对象和底层实现的关p;一旦这U关pd立v来,开发h员就可以为所有的数据讉K对象~写Ҏ的代码生成工兗?/P>
生成数据讉K对象的信息通常存储在一个开发h员定义的描述文g中,如果对于数据讉K对象的要求过于复杂,开发h员可以考虑使用W三方工h为关pd数据库提供对象对关系的映。这些工具通常是一些GUIE序Q可以用来将业务对象映射为持久性的存储对象Qƈ定义中间q作的数据访问对象,在映完成的时候,q些工具可以自动地生成代码,q提供一些相应的功能Q如~存l果、缓存查询、与应用服务器整合、与W三方品整合等?/P>
(2)数据讉K对象代理(Factory for Data Access Objects) 当底层的数据存储不会L改变的时候,开发h员可以采取这U方法来实现相应的,数据讉K对象Q图10是这U方法的cd?/P>
?0 使用DAO代理cd 当底层的数据存储可能会变化的时候,开发h员可以采用抽象代理的Ҏ来实现数据访问对象;抽象代理的方法会创徏一些虚拟的数据讉K对象代理和各U类型的实际数据讉K对象代理Q每U对象对应一U持久性存储介质的实现Q一旦组件得到这些代理,可以利用来创徏需要用的数据讉K对象?/P>
?1l出了这U情늚cd。该cd表示了一个基的数据访问对象代理,它是一个抽象类Q被其他一些实际的数据讉K对象代理l承以支持特定的数据讉K函数Q用户可以得C个实际的数据讉K对象Qƈ利用它来创徏需要的数据讉K对象而访问相关的数据Q每一个实际的数据讉K对象都负责徏立对于数据源的连接,q得到和理所支持的业务数据?/P>
?1 抽象代理使用DAO 下图12是这U情况下的序列图?/P>
?2抽象代理使用DAO序列?/P>
q种设计模式的优势: q种设计模式的缺P MQ在开发h员选择不同模式的时候,应该注意Q一定的模式对应于一定的应用层次。比如说Q与视图和显C相关的模式是在Web层应用的。而一些与业务逻辑控制相关的模式则是与EJB层次相关的。另外一些关于读取数据和分派操作的模式则适用于不同的层次之间 7、值对象或传输对象 值对?value object)模式通过减少分布式通信的消息而促q数据的交换Q通常q里所指的通信是在Web层和EJB层之间。在一个远E调用中Q一个单一值对象可以被用来取出一pd相关数据q提供给客户?/P>
q种设计模式的出现是Z客户需要与ejb大量C换数据的情况。具体来_在J2EEq_中,应用pȝ通常服务器端的E序lg实现Z话bean和实体beanQ而这些组件的部分Ҏ则需要将数据q回l客Pq种情况下,通常一个用户会重复调用相关Ҏ多次Q直到它得到相关信息Q应该注意的是,多数情况q些Ҏ调用的目的都是ؓ了取得单一的信息,例如用户名或者用户地址{?/P>
显而易见,在J2EEq_上,q种调用基本上都是来自远E的。也是_用户多次调用相应的方法会lWeb带来极大的负担,即用户和EJB容器加蝲相同的JVM、OS和计机上运行EJBE序Q由于方法调用被~省地认为是q程dQ所以这U问题依然存在?/P>
׃以上所提到的问题,在远E方法的调用ơ数增加的时候,相关的应用程序性能会有很大的下降Q因此利用多ơ方法调用而取得单一的信息是非常低效的;在这U情况,J2EE的研Ih员徏议用传输对象来包含所有的E序数据Q即每次Ҏ调用可以发送和接收q个传输对象Q当用户向EJB发出对于E序数据的请求时QEJB会创个传输对象,它的各个域赋以相关的数|q将整个对象传送给用户?/P>
当EJB使用传输对象的时候,用户可以通过仅仅一ơ方法调用来取得整个对象Q而不是用多ơ方法调用以得到对象中每个域的数|׃传输对象是通过g递而交送给用户的,所以所有对于该传输对象的调用或取值都是本地调用,而不是远E方法调用。不q需要注意的是,q个传输对象必须h对应于每个属性的讉KҎQ或者将所有属性都设ؓ公共的?nbsp; cd13表示了传输对象模式的体系l构?/P>
?3 传输对象cd 在图13中,传输对象首先在EJB中创建,然后q回l远E客P当然Q传输对象也可以Ҏ需要融合其他的设计模式?/P>
?4昄了传输对象模式中的参与模块和它们之间的交互?/P>
?4 传输对象序列?/P>
下面我们说明一下传输对象模式的各个参与模块Q?/P>
(1)客户(Client)。客户代表了EJB所提供服务的用者,通常是运行于用户l端的应用程序?/P>
(2)业务对象。业务对象表C在一个模式中׃话bean、实体bean或数据访问对?Data Access Object)实现的角艌Ӏ业务对象通常负责创徏传输对象QƈҎh其传送到相关的用P业务对象也可以从用户中取得一个传输对象格式的数据Qƈ应用q些数据来执行一些更新?/P>
(3)传输对象。传输对象是一个可序列化的Java对象。在q个对象的类中,通常会有一个包含所有域的构造函敎ͼ用来创徏q个传输对象?/P>
q个传输对象中的成员变量基本都被定义为公共,从而无需为它们提供相关的讉KҎ。当然如果存在一定安全的需要,相关的成员变量也可以设ؓ保护或私有,q且l定各自的访问方法。由此可见,传输对象的设计是随着应用pȝ的需要不同而改变的Q是否将对象中的成员变量设ؓ公共Q或提供一定的讉KҎQ将是一个很重要的设计问题?/P>
通常在实现这个模式时Q最多采取的是可更新的传输对象策略和多传输对象策略?nbsp; 在可更新的传输对象策略中Q传输对象不仅可以从服务于用L业务对象中取得相关信息和数据Q还可以从业务对象中得到用户对于数据所需要进行的改变?/P>
?5以类图表的Ş式表明了业务对象和传输对象之间的关系?/P>
?5 可更C输对象类?/P>
业务对象创徏了传输对象。而用户通过讉K业务对象Q既得到了所需的信息,也对相关数据做出了一定的修改Qؓ了能够得用户可以修改业务对象各个域的取|q个对象必须提供一定的变值方法,而出于对Web负担的考虑Q业务对象所提供的方法最好以传输对象为参数。相应地Q这些方法可以去调用传输对象所提供的方法,来设|传输对象的各个成员变量的取|同时在传输对象的Ҏ中,我们也可以植入数据验证和完整性检查的逻辑Q这样在用户从业务对象的Ҏ得到传输对象Ӟ可以直接调用传输对象的成员方法进行本地数据访问,当然q种本地数据讉K不会影响C务对象?/P>
当用戯用业务对象的变值方法时Q该Ҏ会将用户端的传输对象序列化,再将它发送给业务对象Q业务对象接收到更新的传输对象,便将q些更新写回到自q对象拯中去Q?nbsp; q里需要说明的是,上面提到的写回只是涉及到被更新的变量Q而不是全部变量的写回Q因此我们需要在传输对象中另讄一个变量,来指定哪些成员变量被用户更新q,q也׃得这U模式的设计相对复杂Q开发h员需要考虑同步化和版本控制的问题?/P>
?6昄了这个更新过E的序列图?/P>
?6 可更C输对象序列图 多传输对象的Ҏ是指一个单一的业务对象可以根据用戯求制造多个不同的传输对象。也是_业务对象和它所创徏的传输对象保持一对多的关pR类?7表示了这U实现方法的各个参与模块以及它们之间的调用关pR?/P>
?7 多传输对象类?/P>
当一个用户需要Acd的传输对象时Q他会激zȝ关EJB的getDataA()Ҏ来取得传输对象AQ当他需要Bcd的传输对象时Q他会激zgetDataB()Ҏ来获取传输对象BQ依此类推。序列图18表示了这一q程?/P>
?8 多传输对象序列图 使用q种设计模式Q应用系l的实体bean及其q程接口会变得十分简单。实体bean中无需再ؓ每一个成员变量都实现一个set()和get()ҎQƈ在远E接口中实现相应的定义。用h需再进行多ơ的Ҏ调用来取得信息和数据Q所需要的只是一ơ方法调用以获得整个传输对象。当然这里需要考虑Web负担和大量数据一ơ传输的权衡。开发h员可以根据不同的需要来选择不同的实现方法?/P>
如上所qͼ用户和实体bean之间可以通过在一ơ方法调用中使用传输对象而交换所有的数据Q也是说传输对象作为数据蝲体工作,q减了q程的方法调用,从而大大减MWeb负担。通过使用传输对象的方法,我们也将有可能减实体bean和其传输对象间的代码重复。不q在使用可更新的传输对象ҎӞ用户可以修改其本地的传输对象Q之后再其传送回业务对象中,后者将所需的更新整合到自己一端;但是q样一来,׃存在一个版本控制的问题Q不同的客户可能在同时修改相同类型的传输对象Q而如果相关的业务对象没有发现q一点的话,可能׃造成一些用L数据没有得到及时更新Q而另外一些用L数据又被覆盖的情况;在系l设计中必须考虑q个问题?BR> 8、截取过滤器 截取qo?intercepting filter)主要用于对于用户h的之前处理和之后处理Q也是说它对于客户的请求用了额外的操作。比如说Qservlet可以处理一个网站的所有客戯求ƈ提供一个核心的认证机制?/P>
q种模式主要工作于表C层Q负责处理不同类型的hQ同时也需要进行多U不同的处理。在q些h中,有一些请求会直接传送给后端模块处理Q而另外一些请求则先会在过滤器里解释或补充内容Q之后才能传送给后端模块。这U模式的提出主要是由于一个客LWeb讉K和系l响应都需要一定的预处理和后处理,例如用户w䆾、用L境信息、用戯求的合法性等。通常q些处理的结果都会决定用Lh是否能够q行Q或是系l的响应应该用什么格式来表示?/P>
对于q种预处理和后处理问题,传统上,开发h员会设计一pd额外的检程序模块,也就是一整套if/else语句Qƈ且指定如果其中Q何一个检失败,所有的处理工作都会退出。显Ӟq种Ҏ是存在很大弊端的Q即代码的可L、可l护性都会被大大降低Q同时将工作融于一般的E序模块Q得整个程序的模块性难以保证?/P>
解决q种问题的关键在于,设计一U简单的技术,以能够添加或U除额外处理的模块,而这些模块通常都能够完成一定的和qo功能。根据以上的讨论QJ2EE研究人员提出了设计模?---截取qo器作x案,q种模式可以在不影响核心处理模块的情况下Q实现可插入的过滤器来执行一般的处理功能?nbsp; 从理Z来说Q这U过滤器可以截取客户h和系l响应,q进行相应的预处理和后处理;同时开发h员也可以随时Ҏ需要移除这些过滤器Qƈ不用担心会改变Q何其他模块?nbsp; 我们q里所说的预处理和后处理功能,通常是指一些基本的pȝ服务Q如安全、登录,pȝ调试{。执行这些功能的qo器通常是需要与核心模块分开的,q且׃pȝ职能或规则的变化Q这些模块随时可能被d或删除?/P>
下面提供一些关于截取过滤器的图C,以帮助大家更好地理解q种设计模式Qƈ合理地加以运用。图19表示了截取过滤器模式的整体结构,?9昄了截取过滤器中的参与模块和相互之间的联系?/P>
?9 截取qo器模?/P>
?0 截取qo器序列图 下面我们分别来说明图20中的各个模块Q?/P>
(1)qo理?Filter Manager)。过滤管理器负责qo器的主要处理工作Q即创徏qo器链对象以及相应的过滤器l徏Qƈ初始化整个处理过E?/P>
(2)qo器链(Filter Chain)。过滤器链是一l互不依赖的qo器有序集合?/P>
(3)qo?Q过滤器2Q过滤器3(FilterOneQFilterTwoQFilterThree)。这些都是提供不同服务的qo器,而过滤器铑ֈ负责它们的协调工作?/P>
通过采用q种设计模式Q应用系l可以取得更方便的中心控Ӟq是׃qo器可以提供处理多U请求的中心模块Qƈ能根据后端的处理模块而解释和润色用户的请求,使得该请求能更好C处理模块所提供的功能匹配。另外,qo器通常可以不同种cȝ服务聚集在一Pq提供相当灵zȝ服务l合Q应用系l可以通过使用截取qo器提高其重用性,qo器可以随时根据需要从其他E序模块中插入或U除Qƈ且由于它们通常h标准的接口,开发h员可以用一l类似的qo器,q在不同的情况下q行全组的重用?/P>
采用q种设计模式也会带来一定的问题Q即在过滤器之间׃n信息变得非常困难,q是׃Ҏ其定义和需求,每个qo器的设计和开发都大相径庭。因而如果在不同的过滤器之间需要共享信息的话,其代价将是非常昂늚?/P>
作者:务实Q多q从事J2EE|站及应用系l项目的开发和应用?/P>
参考资料: 《J2EE设计开发编E指南?nbsp; Rod Johnson 电子工业出版C?/P>
《J2EE参考大全?nbsp; Jim Keogh 电子工业出版C?/P>
《实用J2EE设计模式~程指南?Craig A.Berry 电子工业出版C?/P> 目前大多C业采用J2EE技术的l构设计与解x案。对于我们学习和研究J2EE体系l构来说Q了解与掌握J2EE体系l构的设计方法及一些常用模式是必须的;模型-视图-控制(model-view-controlQ简UMVC)l构是目前最常见的J2EE应用所Z的体pȝ构,MVC主要适用于交互式的Web应用Q尤其是存在大量面及多ơ客戯问及数据昄Q相比较而言Q一个工作流体系l构更多应用于过E控制和较少交互的情况下Q除了体pȝ构外QJ2EE的设计模式对我们解决应用pȝ的设计也有很大的帮助?/P>
模型-视图-控制l构是交互式应用E序q泛使用的一U体pȝ构。它有效地在存储和展C数据的对象中区分功能模块以降低它们之间的连接度Q这U体pȝ构将传统的输入、处理和输入模型转化为图形显C的用户交互模型Q或者换一U说法,是多层次的Web商业应用QMVC体系l构h三个层面Q模型(ModelQ、视?View)和控?Controller)Q每个层面有其各自的功能作用QMVC体系l构如下Q?/P>
? MVC 体系l构 模型层负责表辑֒讉K商业数据Q执行商业逻辑和操作。也是_q一层就是现实生zM功能的Y件模拟;在模型层变化的时候,它将通知视图层ƈ提供后者访问自w状态的能力Q同时控制层也可以访问其功能函数以完成相关的d?/P>
视图层负责显C模型层的内宏V它从模型层取得数据q指定这些数据如何被昄出来。在模型层变化的时候,它将自动更新。另外视囑ֱ也会用L输入传送给控制器?/P>
控制层负责定义应用程序的行ؓ。它可以分派用户的请求ƈ选择恰当的视图以用于昄Q同时它也可以解释用L输入q将它们映射为模型层可执行的操作Q在一个图形界面中Q常见的用户输入包括点击按钮和菜单选择。在Web应用中,它包括对Web层的HTTP GET和POST的请求;控制层可以基于用L交互和模型层的操作结果来选择下一个可以显C的视图Q一个应用程序通常会基于一l相兛_能设定一个控制层的模块,甚至一些应用程序会Ҏ不同的用L型具有不同的控制层设定,q主要是׃不同用户的视图交互和选择也是不同的?/P>
在模型层、视囑ֱ和控制层之间划分责Q可以减少代码的重复度Qƈ使应用程序维护v来更单。同时由于数据和商务逻辑的分开Q在新的数据源加入和数据昄变化的时候,数据处理也会变得更简单?BR>
一、J2EE的模?视图-控制QMVCQ体pȝ?/H5>
二、J2EE设计模式
一个设计模式描qC对于特定设计问题被验证的解决ҎQ它l合了所有开发者对q个问题所在领域的知识和见解;同时也是对于常见问题的可重用ҎQ它们一般适用于单个问题,但是l织在一起就可以提供整个企业pȝ的解x案。下面我们列丑օU常用于J2EEq_的设计模式,q对每种模式作简单的介绍Q便于大家学习、理解与灉|应用?/P>
1、前控制?/B>
前控制器(front controller)主要提供一U可以集中式理h的控制器Q一个前控制器可以接受所有的客户hQ将每个h递交l相应的h句柄Qƈ适当地响应用戗?/P>
前控制器也是表示层的设计模式Q它的出C要是׃表示层通常需要控制和协调来自不同用户的多个请求,而这U控制机制又Ҏ不同的需要,可能会集中式控制或分散式控制。换句话_是应用pȝ需要对于表C层的请求提供一个集中式控制模块Q以提供各种pȝ服务Q包括内Ҏ取、视囄理和览Q如果系l中没有q种集中式控制模块或控制机制Q每个不同的pȝ服务都需要进行单独的视图处理Q这样代码的重复性就会提高,致ɾpȝ开发代h高;同时Q如果没有一个固定模块管理视图之间的览机制Q致使其览功能下放于每个不同的视图中,最l必得系l的可维护性受到破坏;本文中我们主要讨论的是集中式控制模块Q而不是分散式控制Q因为前者更适合于大型的应用pȝ?/P>
Z上面所说的问题Q研Ih员提Z前控制器的设计模式。在q种模式中,控制器提供一个处理不同请求的控制点,q里的处理工作包括安全事务、视N择、错误处理和响应内容的生成;通过这些处理工作集中在一点进行,大大地减低了Java代码量,同时q种Ҏ也可以减在视图模块的程序逻辑Q保证了在不同请求之间可以重用大量的逻辑代码。通常Q控制器都是和一个分z件联合工作的Q分z件主要是用于视图理和浏览,也就是ؓ用户选择下一个应该显C的视图Qƈ同时提供对于相关昄资源的控制。分z件可以包含在控制器之内,或是在另外一个单独的lg中;虽然前控制器模式推荐对于全部的请求用统一处理Q但是它也没有限制在一个系l中只能h一个控制器Q在pȝ中的每个层次都可以具有多个控制器Qƈ且映至不同的系l服务,下图2昄了前控制器的cd?/P>
? 前控制器的类?/P>
?昄了前控制器的序列图,表示一个控制器如何处理相关的请求?/P>
?前控制器序列?/P>
下面我们来讨Z下图3的各个组件?/P>
2、控制器
控制?controller)是负责处理各U客戯求的控制点,q可以将一定的职能(如用戯证等)下放l帮助类?/P>
(1)分派lg(Dispatcher)。一个分z件主要是用于视图的管理和览Qؓ用户选择下一个可以显C的视图Qƈ理相关的显C源;分派lg可以在一个控制器内运行,或者作Z个单独的lg与控制器协同工作Q开发h员可以在分派lg中实现静态的视图分派技术,或是复杂的动态分z?/P>
(2)帮助c?Helper)。帮助类负责帮助一个视图或控制器来完成其处理工作,因此Q帮助类h多项职责Q包括收集数据、存储中间数据模型等Q另外,帮助cM可以在保证数据完整性和准确性的情况下,Z同显C需求修Ҏ据模型;也就是说Q根据用LhQ帮助类可以向视图提供未l处理的原始数据Q或是已l格式化后的Web内容Q一个视囑时可以和多个帮助cd同工作,而后者通常是由JavaBeans和标{?tag)实现的?BR>
3、视?nbsp;
视图(view)负责向用hCZ息,而帮助类则负责支持视囄工作Q即打包和徏立相应的数据模型Q下面我们介l几U可以实现控制器的方法?/P>
1Q基于Servlet前控制器
q种Ҏ使用servlet来实C个控制器Q尽在语法上相差无几,但是它比使用JSP来实现要优越一些;因ؓ控制器所q行的请求处理,多数都是与程序运行和控制动相关的,q些处理工作虽然与显C模式相养I但是实际上是逻辑独立的,所以它们更适合在servlet中实玎ͼ而不是JSP技术中Q用这U方法也存在一些弱点,比如说servlet无法使用JSPq行环境的资源,如请求参数等Q但是这个弱点也不是不能解决的,我们可以在servlet中徏立相关的句柄来访问同L资源Q当然其代码会变得繁琐一炏V?/P>
2Q基于JSP的前控制?/B>
q种Ҏ使用JSP面实现控制器,管语法上相同,但是ServletҎ要比其优一些;因ؓ控制器所处理的逻辑一般都不是有关昄模式的,所以在JSP面中实现控制器g有点风马牛不相及Q用这U方法也不利于开发团队的角色和职责的分配Q即软g开发h员需要在负责昄逻辑的JSP面中修改请求处理的代码Q通常Q这U工作都是相当复杂的Q尤其考虑整个JSP面的编E、编译、测试和调试错误?/P>
3Q控制器之中的分z?/B>
如果分派lg没有较多功能Q开发h员可以在控制器实现该lg?/P>
4Q基前端
Z使用servlet实现前控制器Q这U方案徏议实C个控制器作ؓ基础c,q样其他的控制器可以在其之上扩展Q这个基cd以包含一些通用的逻辑实现Q它的子cd会重载这些实C码,q种Ҏ也有一定的~陷Q当有许多子cȝ承这个基c,q大量地重用代码Ӟ那么有可能出现一个类的改变会影响到所有子cȝ情况?/P>
5Q用qo器实现前控制?/B>
qo器提供了与用戯求的中心处理相类似的功能Q也是_控制器的一些功能可以由qo器来实现Q这U方案的qo器主要负责处理请求的截取和解释,而不是请求的处理和响应的生成Q通常可以为应用系l提供一个核心控制点Q以处理所有的pȝ服务和程序逻辑Q核心控制也p明了所有的h都可以简单地被跟t和记录Q从而方便各U服务功能的实施Q当Ӟ它也存在一些缺点,一个核心控制点的小问题可能会引发系l的崩溃Q但在应用系l的实际开发中Q这q不是个问题Q因为通常我们都会在同一个层面上实现多个控制器,从而避免了q个~陷Q在控制器中Q开发h员可以很方便地实C个检查安全机制的lgQ从而可以在最外层屏蔽对系l的恶意讉KQ另外用控制器也会提高pȝ模块的可重用性,其在控制器同时使用帮助cȝ时候?/P>
4、视囑ָ?/B>
视图帮助(View helper)是属于表C层的设计模式,一个视囑ָ助可以包含相兌图中的数据访问和内容昄的逻辑Qƈ可以_化视图;昄逻辑主要是关于如何格式化面上的数据Q而访问逻辑则是关于如何取出数据Q视囑ָ助通常用来昄数据的JSP标记(tag)或是d数据的JavaBean?/P>
q种设计模式的出C要是׃目前的应用系l通常需要实时地开发显C内容,q且能处理动态的E序数据。如果这些程序数据的讉K逻辑和显C逻辑的关p过于紧密,则系l的表示层就会经帔R要改动,从而系l的灉|性、重用性会大大地受到破坏;同时在相同的模块中实现访问逻辑和显C逻辑会影响pȝ的模块化Q也会得开发团队的d划分不清?/P>
一个视N常包含格式化信息,q将其处理Q务分发给自己的帮助类Q后者通常是用JavaBeans或标?tag)来实现的Q帮助类同时可以存储视图的中间数据模型ƈ实现数据适配器的功能Q即适当地{化数据格式;开发h员可以采用多U方法实现视囄Ӟ通常Q开发h员可以用JSP来实玎ͼq且q也是一U值得推荐的方法。当Ӟ相应地开发h员也可以使用Servlet来实现它Q将视图中一定的E序逻辑植入到帮助类中,会有利于应用pȝ的模块化和可重用性。系l可以用同一个帮助类Z同的用户昄不同的数据信息,q在不同的显C格式下昄Q通常Q如果开发h员发现视囄JSP面中存在大量的脚本代码Ӟ可以考虑使用视图帮助q种模式了,因ؓ在这U情况下Q基本都是程序逻辑和显C逻辑hq于紧密的联p;q时开发h员可以将一些适用于所有类型的h的逻辑处理攄C定的帮助cMQ而根据需要,也可以将另外一些逻辑处理攄在视囑ֱ上的其他E序模块中,比如说以前讨的截取过滤器?nbsp;
视图帮助q种模式的设计理念主要是分离应用pȝ的逻辑职责Q下面我们提供一些图C,以方便大家更好地理解q种模式?/P>
?以类?class diagram)的Ş式说明了视图帮助的系l结构?/P>
? 视图帮助cd
?表示了视囑ָ助模式的序列图,它表明了q种模式中的主要成分及互怹间的q行情况Q不q需要说明的是,在很多应用系l中Q客L和视囑ֱ之间会存在一个控制器加以适当的调节?/P>
?视图帮助序列?/P>
在类图表中,大家可以发现Q可能存在没有Q何相兛_助类的视图,q种情况下,通常代表视图的JSP面会有一些静态的或小数量的脚本代码?/P>
q里我们对于序列图中的各个元素加以简单的介绍Q?/P>
(1)视图(view)。视图负责向用户展示动态数据信息,而帮助类则负责支持视囄工作Q即打包和徏立相应的数据模型?/P>
(2)帮助c?helper)。一个帮助类负责帮助视图或控制器完成相关的处理工作,包括攉数据、存储中间模型等Q帮助类也可以在保证数据完整性和准确性的情况下,Z同显C需求修Ҏ据模型,也就是说Q根据用LhQ帮助类可以向视图提供未l处理的原始数据Q或是已l格式化后的Web内容Q一个视囑时可以和多个帮助cd同工作,而后者通常是由JavaBeans和标?tag)实现的?/P>
(3)值bean(ValueBean)。值bean实际上是用于存储中间数据模型的帮助类的另一U叫法,例如在序列图5中,business service根据请求返回了一个值bean?/P>
(4)业务服务(business service)。业务服务是指用戯囑־到的Q应用系l可以提供的相关服务Q通常来说Q业务服务可以通过一个业务代?business delegate)来访问,而后者主要是提供对于业务服务的控制和保护?/P>
在应用系l的视图模块中用帮助类可以不同的E序逻辑很好地分d来,q在视图模块之外为开发h员提供设计程序逻辑的空_ZJavaBean和标?tag)所开发的帮助c通常都可以被多个视图模块重用Q因此也提高了组件的重用性和可维护性;把显C逻辑从数据处理逻辑分离出来Q也有利于开发团队中角色及h物的划分Q比如说Q如果各U程序逻辑q于l合的话QY件开发h员可能需要在HTMLQ网中修改代码而Web设计师则需要在处理数据讉K的JSP中修攚w面布|,q些情况都可能会Dpȝ设计和开发中׃不同技术h员的介入Q而生相关的问题?BR>
5、会话面
会话?session facade)模式在合作的企业对象间调节操作,q将应用函数合成一个单一单的界面Q它减少了类之间合作的复杂性,q得类的调用者在该类变化的时候无需改动Q这U模式通常以一个会话bean实现Q以用来隐藏底层ejb的复杂交互?/P>
q种设计模式出现的背景在于EJB通常既包括程序数据,又包括程序逻辑Q而这些代码都会通过一定的界面作用于客户层Q在多层ơ的J2EEq_应用E序中,׃造成一定的困难?/P>
具体来说Q在J2EEq_上的多层ơ系l中Q通常会存在以下的问题Q?/P>
(1)层次之间联系q于紧密Q客户层和后端的业务对象h较强的依赖关p;
(2)在客户和服务器之间有多次Ҏ调用Q因而导致了Web性能斚w的问题;
(3)~Z一定的客户讉K机制Q得一些后台对象被随便讉K?/P>
一个多层次的J2EE应用E序通常h很多由EJB实现的服务器端对象,它们通常负责提供pȝ服务、数据信息等Q也是说作Z务对象,它们既包括相关的E序数据Q也包括其程序逻辑Q在J2EE应用pȝ中,负责E序逻辑的对象通常׃话bean实现Q而表C持久性存储,q在多个用户间共享的对象则由实体bean来实玎ͼ当然Q应用系l的用户需要访问企业对象来满自己的需求,如果企业对象向用h供接口,用户可以直接C相关对象通信Q但是这样一来,用户必须负责理所调用的企业对象之间的关系Qƈ且能够处理其间的业务程Q然而,如果用户和业务对象之间存在过于直接的交互Q两者的联系׃q于紧密Q同时也使得用户q于依赖企业对象的具体实玎ͼq负责管理与交互q程有关的业务对象查扑֒创徏Q以及不同的对象间相互调用的关系Q甚至一些时候用戯需要管理多ơ调用之间的事务理环节?/P>
在用户需求不断增加时Q这也是应用pȝl常发生的情况,用户与不同的企业对象之间的交互也会变得越来越复杂Q而企业对象可能需要一定内部的更新才能满前者的需要,但是q样的话用户又需要根据企业对象实现的变化而做出相应的改变Q这U情况将为应用系l带来相当大的麻烦;在访问EJB应用pȝӞ用户需要与q程对象q行交互。如果用L接与所有相关的业务对象交互的话Q将带来很大的Web负担Q因为对于每一个ejb的激z,都将产生一ơ远E的调用Q而如果存在大量的pȝ用户Q用户与对象间的交互将为Web通信带来很大的压力,使系l性能受到很大破坏Q如果用户可以直接访问后端的企业对象Q但是系l中又缺一个统一的用戯问机Ӟ那么q些讉K很有可能变得杂ؕ无章Q引Ll性能的下降,甚至D一些安全问题?/P>
Z解决以上的问题,开发h员可以采用会话面的设计模式,即用会话bean来实C个面(facade)来包含一个工作流中所有相兛_象的交互Q这个会话面负责理业务对象Qƈ向用h供一个统一的服务访问层Q会话面可以面向底层对象的交互过E,q提供一个仅仅包含必L供的接口的服务层Q由此它复杂的对象交互和用户之间隔d来; 会话面也负责理企业数据和企业对象之间的交互Qƈ表达其中需要的企业逻辑Q因此会话面也可以管理企业对象之间的作用关系Q同ӞҎ工作的需要,会话面也理对象的创建、查找、修改和删除?/P>
在一个复杂的应用pȝ中,会话面可以将其生命周期的理下放C个单独的帮助对象去,比如_会话面可以将理会话和实体bean生命周期的工作交l服务定位对象; 同时Q在应用pȝ中,查业务对象之间的作用关系也是非常重要的,一些关pd能是暂时的,卛_使用于一定的交互q程Q而另外一些关pd是永久的Q暂时的关系适合建模于会话面中的工作,怹的关pd需要具体情况具体分析?/P>
?中的cd要描qC会话面的设计模式Q图7l出了会话面的序列表C,卛_与组件及其交互关pR?/P>
? 会话面类?/P>
?会话面序列图
q里我们对于?的各个组件加以简要的介绍Q?/P>
(1)客户(Client)。这表示会话面的客户Q即需要访问相关企业服务的客户端应用程序,当然也可以是在同一层面或不同层面的另外一个会话bean?/P>
(2)会话?Session Facade)。会话面通常是用会话bean来实现的Q它理着多个企业对象的作用关pdƈ提供一个高层次的抽象界面给用户?/P>
(3)业务对象(Business Object)。业务对象是一个可以用多个不同设计方案的对象Q例如会话bean、实体bean和数据访问对象。在?中业务对象负责提供数据和服务Q而会话面则需要与多个业务对象实例交互而获得相应的服务?/P>
会话面实际上是业务层的一个控制对象,它负责控制用户与企业数据和企业服务对象之间的交互Q在一个复杂的应用pȝ中,甚至可能会有多个会话面作为用户和对象模块之间的中介?/P>
下面介绍两种实现会话面的常见Ҏ?/P>
(1)无状态的会话?/B>
在实C话面的时候,首先应该军_是用状态化q是无状态的会话bean来实玎ͼq主要取决于会话面所建模的业务流E;如果一个业务流E只需要一ơ方法调用就可以实现其服务,那么可以用无状态的会话bean来实现它?/P>
(2)状态化的会话面
当一个业务流E需要多ơ方法调用来实现其服务时Q开发h员最好用状态化的会话bean来实现这一程Q因为每ơ方法调用的状态信息都必须在会话bean中保存?/P>
通过在应用系l中采用会话面的设计模式Q将在系l中得到以下的收益:
①ؓ用户提供一个简单的接口Qƈ隐藏所有与pȝlg复杂的交互过E;
②减暴露给用户的企业对象,从而降低它们之间的依赖关系Q?/P>
③向用户隐藏pȝlg间的交互q程和依赖关p,从而得系l更加容易管理,q提供相当的灉|性;提供一套统一的用戯问机Ӟ便于理用户对于pȝ服务的请求与讉K?/P>