帝国软件
  设为首页 加入收藏 关于我们
 
解密帝国网站管理系统
栏 目:
 
您的位置:首页 > 技术文档 > JAVA编程
J2EE Design Patterns
作者:佚名 发布时间:2005-04-02 来源:不详
 
  什么是Design Patten?

  简单来说,Design Pat
些相同或者相近的问题,每
们提供一些能够解决这些常
ten 就是一个常用的方案。 在
次我们都会去寻找一个新的解决
见问题的,被证实可行的方案,
我们的开发过程中,经常会遇到一
方法,为了节省时间提高效率,我
构成一个统一的资源库。
  一个Design Patten描
最常用的模式。 这些模式
设计J2EE应用时得到体现。
述了一个被证实可行的方案。这
可以被重用,有良好的伸缩性,

些方案非常普通,是有完整定义的
而这些Design Patten的优势将在


  1. Model-View-Controller

  a. 问题                                                                    
  如果开发一个企业级应
况是,我们必须面对运行在
,我们不得不开发不同的应
起,可能会出现重复的数据
用,只需要一种客户端的话,那
各种设备上客户端,象PDA,WAP
用程序来处理来自不同客户端的
访问,导致整个开发周期没有必
么一切都非常容易解决。但真实情
浏览器以及运行在桌面上的浏览器
请求。数据访问与现实将混淆在一
要的延长。

  b. 建议的解决方法                                                          
  Model-View-Controller (MVC) 开发
访问和数据表现。你可以开发一个有伸缩
所示为整个模式的结构。MVC模式可以被
模式被证明是有效的处理方法之一。它可以分离数据
性的,便于扩展的控制器,来维护整个流程。如图1
映射到多层企业级的J2EE应用上。
  § 所有的企业数据以及商业逻辑可以作为模式。                                  
  § 视图可以通过模式访问数据,并
改变的时候,数据显示也必须同时改变。
根据客户端的要求来显示数据。视图必须保证当模式

  § 控制器用来结合模
并且根据请求以及执行结果
式和视图,把客户端来的请求转
来决定下一次显示那一个视图。
换成模式能够理解并执行的请求,

  根据以上的逻辑,你可以象这样建立一个应用:                                    
  § 应用的商业逻辑由MVC中的模式也
对数据的访问请求。
就是EJB来表现。模式必须处理由控制器传递过来的

  § 多个页面组成了MVC中的视图,这些视图必须随模式一起更新。                
  § 控制器是一系列接
并决定显示那一个页面当模
收用户动作的对象,他们把用户
式处理完请求后。
的请求转换成模式可理解的请求,


  c. 要点                                                                    
  § MVC结构适用于那些多用户的,可扩展的,可维护的,具有很高交互性的系统。  
  § MVC可以很好的表达用户的交互和系统模式。                                
  § 很方便的用多个视图来显示多套数据,是系统很方便的支持其他新的客户端类型。  
  § 代码重复达到最低。                                                        
  § 由于分离了模式中
产品推向市场的时间。
的流控制和数据表现,可以分清

开发者的责任,另外,也可以加快


  2. Front Controller

  a. 问题                                                                    
  MVC给出了一个整个应
某一个应用中,用户看到的
而这些页面之间含有高度的
面的集合,维护和扩展变得
用的松散的耦合架构。现在来看
视图和他所做的操作密切相关。
依赖性。在没有任何模式的时候
异常困难。
一下这样一个经常发生的情况。在
这是一些具有高度交互性的页面,
,这个应用只是一个许多独立的页

  § 当一个页面移动后,其他含有这个页面链接的文件,都必须修改。                
  § 当有一系列页面需要口令保护时
记。
,许多配置文件需要修改,或者页面需要包含新的标

  § 当一个页面需要一个新的表示层时,页面中的标记要被重新安排。                
  当这个系统变得复杂时,这些问题将
管理控制器和视图之间交互的问题。
变得更糟。如果用MVC来解决的话,就变成一个如何


  b. 建议的解决方法                                                          
  前台控制模式可以解决
主要的对象将处理所有的请
视图显示以及其他功能实现
可以在所有视图中反映出来
这个问题。这个模式中,所有的
求,决定以后显示那一个视图,
集中到一个主要的对象中,将使

请求都被传送到一个对象中。这个
以及实现必要的安全需求。对于把
修改变得很容易,对应用的修改,


  c. 要点                                                                    
  § 这个模式对于需要
效的。
在多个含有动态数据的页面之间

进行复杂导航的系统来说,是很有

  § 这个模式对于要在所有页面中都包含模板,转换等的应用来说,也是很有效的。    
  § 由于视图的选择集中在前端控制
置。
器上,因此,视图的导航变得更加容易理解和便于配

  § 视图重用和变更会更加容易。                                                
  § 视图之间的复杂交
得难以维护。不过,大部分
互,使得控制器变得复杂。从而
情况下可以用XML映射来解决。
,当应用发展的时候,控制器将变

  § 实现应用要求的安全性检验变得很简单。                                      
  § 这个模式不适合小型的,只显示静态内容的应用。                              

  d. 样例                                                                    
  § RequestMappings.x
ml 文件映射了传入的请求,处
理器以及下一个页面

  useRequestHandler="true"                             
  requiresSecurityCheck="true"                     
  nextScreen="screen2.jsp">

  com.blah1.blah2.blah3.request1Handler    

  以上这个文件是控制器的指定配置,控制器的代码如下:                            
  § FrontControllerImpl.java 利用
上面的XML实现了控制器
  // all required imports                                
  // exceptions to be
caught appropriately whereve
r applicable

  public class FrontControllerImpl
extends HttpServlet {


  // all required decl
arations, definitions
  private HashMap requestMappings;              

  public void init() {                                      
  // load the mappings
from XML file into the hash
map
  }                                                                            

  public void doPost(HttpServletRe
quest request,
  HttpServletResponse response)                    
  throws IOException, ServletException     
  {                                                                            
  doGet(request, response);                            
  }                                                                            

  public void doGet(Ht
tpServletRequest request, Ht
tpServletResponse response)
  throws IOException, ServletException {  
  String currentPage= request.getP
athInfo();
  // get all mapping info for "cur
rentPage" from the hashmap
  // if "securityCheck
Required = true", do the sec
urity check
  // if "useRequestHan
specified handler
dler = true", pass on the in

coming request to the

  // forward the results to the gi
ven "nextScreen"
  }                                                                            
  }                                                                           
  用这种方法实现的控制器将很容易维
能解决了。前台控制模式将使在视图和控
护,当应用有新的变动的时候,只要修改XML文件就
制器之前有复杂交互的J2EE应用变得简单。

  3. Session Facade

  a. 问题                                                                    
  前台控制给出了一个基
模式可以使处理页面的现实
更加容易。
于MVC的,能有效管理用户与J2E
顺序和用户的并发请求变得简单

E应用之间进行的复杂交互。这个
。并且使增加和改变页面现实变得

  另外一个常见的问题是
改变。我们来看一下这个问
,当EJB或者业务逻辑发生变化
题。
的时候,应用的客户端也必须随之

  一般来说,为了表现一
用户名和口令,再用一个EJ
号或者修改一个已经存在的
保存,这样的一个流程。
个账户中的用户,我们使用一个
B来管理用户的个人信息,象爱
账号时,必须访问包含账号信息

业务逻辑来表示账户中的信息,象
好,语言等。当要创建一个新的账
的EJB,读取个人信息,修改并且

  当然,这只是一个非常
些服务,检验客户信用卡的
客户端必须访问账户EJB来
何来控制一个用户订单。
简单的例子,实际情况可能比这
有效性,存放订单等。在这个案
完成一系列适当的工作。下面的

个复杂的多,象查看用户定制了哪
例中,为了实现一个完整的流程,
例子显示了一个Servlet客户端如

  A servlet that does
the workflow required for pl
acing an order
  // all required imports;                              
  // exceptions to be caught appro
priately wherever applicable;
  // This servlet assu
mes that for placing an orde
r the account and
  // credit status of
the customer has to be check
ed before getting the
  // approval and committing the o
rder. For simplicity, the EJBs that
  // represent the bus
iness logic of account, cred
it status etc are
  // not listed                                                    

  public class OrderHandlingServle
t extends HttpServlet {


  // all required decl
arations, definitions

  public void init() {                                      
  // all inits required done here                
  }                                                                            

  public void doPost(H
ttpServletRequest request, H
ttpServletResponse response)
  throws IOException, ServletException {  
  // other logic as required                          
  // Get reference to the required EJBs    
  InitialContext ctxt = new Initia
lContext();
  Object obj = ctxt.lo
okup("java:comp/env/ejb/User
Account");
  UserAccountHome acctHome = (User
AccountHome)
  PortableRemoteObject.narrow(obj,
UserAccountHome.class);
  UserAccount acct = acctHome.create();    
  obj = ctxt.lookup("j
ava:comp/env/ejb/CreditCheck
");
  CreditCheckHome creditCheckHome
= (CreditCheckHome)
  PortableRemoteObject.narrow(obj,
CreditCheckHome.class);
  CreditCheck credit = creditCheck
Home.create();
  obj = ctxt.lookup("java:comp/env
/ejb/Approvals");
  ApprovalsHome apprHome = (Approv
alsHome)
  PortableRemoteObject
.narrow(obj, ApprovalsHome.c
lass);
  Approvals appr = apprHome.create();        
  obj = ctxt.lookup("j
ava:comp/env/ejb/CommitOrder
");
  CommitOrderHome orderHome = (Com
mitOrderHome)
  PortableRemoteObject.narrow(obj,
CommitOrderHome.class);
  CommitOrder order = orderHome.create();

  // Acquire the customer ID and o
rder details;
  // Now do the required workflow
to place the order

  int result = acct.ch
eckStatus(customerId);
  if(result != OK) {                                          
  // stop further steps                                    
  }                                                                            
  result = credit.checkCreditWorth
(customerId, currentOrder);
  if(result != OK) {                                          
  // stop further steps                                    
  }                                                                            
  result = appr.getApprovals(custo
merId, currentOrder);
  if(result != OK) {                                          
  // stop further steps                                    
  }                                                                            

  // Everything OK; place the order            
  result = order.place
Order(customerId, currentOrd
er);

  // do further processing as required      
  }                                                                            
  }                                                                           
  以上的代码显示了一个单个的客户端
客户端制定一种处理方法来完成工作流程
有的参与这个流程的客户端都需要改变。
户端都必须知道这一点,如果流程中需要
改。
。如果这个应用支持多种客户端的话,必须为每一个
。如果有一个EJB的实现流程需要改变的话,那么所
如果不同的EJB之间的交互需要改变的话,所有的客
增加一个新的步骤的话,所有的客户端也必须随之修

  这样一来,EJB和客户
,致使网络速度变慢。同样
端之间的改变变得非常困难。客
,应用越复杂,麻烦越大。
户端必须对每个EJB分开进行访问


  b. 建议的解决方法                                                          
  解决这个问题的方法是,把客户端和
式。这个模式通过一个Session Bean,为
当客户端只是使用这个接口来触发流程。
户端无关。
他们使用的EJB分割开。建议适用Session Fa?ade模
一系列的EJB提供统一的接口来实现流程。事实上,
这样,所有关于EJB实现流程所需要的改变,都和客

  看下面这个例子。这段代码用来控制与客户相关的订单的处理方法。                  
  // All imports required                                
  // Exception handling not shown
in the sample code

  public class OrderSe
ssionFacade implements Sessi
onBean {

  // all EJB specific methods like
ejbCreate defined here
  // Here is the business method t
hat does the workflow

  // required when a c
ustomer places a new order

  public int placeOrder(String cus
tomerId, Details orderDetails)
  throws RemoteException {                              
  // Get reference to the required EJBs    

  InitialContext ctxt
= new InitialContext();
  Object obj = ctxt.lookup("java:c
omp/env/ejb/UserAccount");
  UserAccountHome acctHome = (User
AccountHome)
  PortableRemoteObject
.narrow(obj, UserAccountHome
.class);
  UserAccount acct = acctHome.create();    
  obj = ctxt.lookup("j
ava:comp/env/ejb/CreditCheck
");
  CreditCheckHome cred
itCheckHome = (CreditCheckHo
me)
  PortableRemoteObject.narrow(obj,
CreditCheckHome.class);
  CreditCheck credit = creditCheck
Home.create();
  obj = ctxt.lookup("j
ava:comp/env/ejb/Approvals")
;

  ApprovalsHome apprHo
me = (ApprovalsHome)
  PortableRemoteObject
.narrow(obj, ApprovalsHome.c
lass);
  Approvals appr = apprHome.create();        
  obj = ctxt.lookup("j
ava:comp/env/ejb/CommitOrder
");
  CommitOrderHome orderHome = (Com
mitOrderHome)
  PortableRemoteObject
.narrow(obj, CommitOrderHome
.class);
  CommitOrder order = orderHome.create();

  // Now do the requir
ed workflow to place the ord
er
  int result = acct.checkStatus(cu
stomerId);
  if(result != OK) {                                          
  // stop further steps                                    
  }                                                                            
  result = credit.chec
kCreditWorth(customerId, cur
rentOrder);
  if(result != OK) {                                          
  // stop further steps                                    
  }                                                                            
  result = appr.getApp
rovals(customerId, currentOr
der);
  if(result != OK) {                                          
  // stop further steps                                    
  }                                                                            

  // Everything OK; place the order            
  int orderId = order.
placeOrder(customerId, curre
ntOrder);

  // Do other processing required                

  return(orderId);                                              
  }                                                                            

  // Implement other workflows for
other order related functionalities (like
  // updating an existing order, c
anceling an existing order etc.) in a
  // similar way                                                  
  }                                                                           
  在模式允许的情况下,Servlet代码将很容易实现。                          
  // all required imports                                
  // exceptions to be caught appro
priately wherever applicable

  public class OrderHandlingServle
t extends HttpServlet {

  // all required declarations, de
finitions

  public void init() {                                      
  // all inits required done here                
  }                                                                            

  public void doPost(HttpServletRe
quest request, HttpServletResponse response)
  throws IOException, ServletException {  
  // other logic as required                          
  // Get reference to the session facade  

  InitialContext ctxt
= new InitialContext();
  Object obj = ctxt.lookup("java:c
omp/env/ejb/OrderSessionFacade");
  OrderSessionFacadeHome facadeHom
e = (OrderSessionFacadeHome)
  PortableRemoteObject.narrow(obj,
OrderSessionFacadeHome.class);
  OrderSessionFacade facade = faca
deHome.create();

  // trigger the order workflow                    
  int orderId = facade.placeOrder(
customerId, currentOrder);

  // do further processing as required      
  }                                                                            
  }                                                                           
  就象上面显示的,客户端的逻辑变得
地方就可以了。客户端可以仍旧使用原来
来响应其他处理器的流程处理。这让你能
例子中,模式提供了很好的伸缩性和可维
非常简单。流程中的任何改变只要修改模式中的一处
的接口,而不必做任何修改。同样,这个模式可以用
用同样的模式来处理不同客户端的不同流程。在这个
护性。

  c. 要点                                                                    
  § 既然这种模式不涉及到数据访问,就应该用Session Bean来实现。    
  § 对于用简单接口来实现复杂EJB的子系统来说,是一个理想的选择。            
  § 这个模式不适用于无流程处理的应用。                                        
  § 这个模式可以减少客户端于EJB之间的通信和依赖。                          
  § 所有和EJB有关的交互,都有同一
用。
个Session Bean来控制,可以减少客户端对EJB的误

  § 这个模式可以使支持多类型客户端变得更容易。                                
  § 可以减少网络数据传递。                                                    
  § 所有的服务器端的实现细节都对客户端隐藏,在改变发生后,客户端不用重新发布。
  § 这个模式可以同样看成一个集中处理器来处理所有的安全或日志纪录。            

  4. Data Access Object

  a. 问题                                                                    
  目前为止,你看到的模
的把应用在多个层上来实现
的数据库语言。如果数据库
型都是用来构建可伸缩的,易于
。但是,还有一点必须强调:EJ
有改变的话,相应的SQL也必须
维护的J2EE应用。这些模式尽可能
B的数据表现。它们包括象EJB这样
改变,而EJB也必须随之更新。
  这些常见问题就是:访
下的代码。
问数据源的代码与EJB结合在一

起,这样致使代码很难维护。看以

  An EJB that has SQL code embedde
d in it
  // all imports required                                

  // exceptions not ha
ndled in the sample code

  public class UserAcc
ountEJB implements EntityBea
n {

  // All EJB methods l
ike ejbCreate, ejbRemove go
here
  // Business methods start here                  

  public UserDetails getUserDetail
s(String userId) {

  // A simple query for this example          
  String query = "SELECT id, name,
userId;
phone FROM userdetails WHERE name = " +



  InitialContext ic =
new InitialContext();
  datasource = (DataSource)ic.look
up("java:comp/env/jdbc/DataSource");
  Connection dbConnect
ion = datasource.getConnecti
on();

  Statement stmt = dbC
onnection.createStatement();

  ResultSet result = s
tmt.executeQuery(queryStr);

  // other processing like creatio
n of UserDetails object

  result.close();                                                
  stmt.close();                                                    
  dbConnection.close();                                    
  return(details);                                              
  }                                                                            
  }                                                                           
  b. 建议的解决方法                                                          
  为了解决这个问题,从而让你能很方
式把数据访问逻辑从EJB中拿出来放入独
在需要数据的时候,通过DAO来访问数据
更新DAO的对象就可以了。看以下的代码
便的修改你的数据访问。建议使用DAO模式。这个模
立的接口中。结果是EJB保留自己的业务逻辑方法,
库。这样的模式,在要求修改数据访问的时候,只要

  A Data Access Object that encaps
ulates all data resource access code
  // All required imports                                
  // Exception handling code not l
isted below for simplicity

  public class UserAccountDAO {                    

  private transient Connection dbC
onnection = null;

  public UserAccountDAO() {}                          

  public UserDetails getUserDetail
s(String userId) {

  // A simple query for this example          
  String query = "SELECT id, name,
userId;
phone FROM userdetails WHERE name = " +



  InitialContext ic =
new InitialContext();
  datasource = (DataSo
urce)ic.lookup("java:comp/en
v/jdbc/DataSource");
  Connection dbConnect
ion = datasource.getConnecti
on();

  Statement stmt = dbC
onnection.createStatement();
  ResultSet result = stmt.executeQ
uery(queryStr);

  // other processing like creatio
n of UserDetails object

  result.close();                                                
  stmt.close();                                                    
  dbConnection.close();                                    
  return(details);                                              
  }                                                                            

  // Other data access
/ modification methods pert
aining to the UserAccountEJB
  }                                                                           
  现在你有了一个DAO对象,利用这个对象你可以访问数据。再看以下的代码。        
  An EJB that uses a DAO                                 
  // all imports required                                
  // exceptions not handled in the
sample code

  public class UserAccountEJB impl
ements EntityBean {

  // All EJB methods like ejbCreat
e, ejbRemove go here

  // Business methods start here                  

  public UserDetails g
etUserDetails(String userId)
{

  // other processing as required                

  UserAccountDAO dao =
new UserAccountDAO();
  UserDetails details
= dao.getUserDetails(userId)
;
  // other processing as required                
  return(details);                                              
  }                                                                            
  }                                                                           
  任何数据源的修改只要更新DAO就可
数据源类型,你可以开发多个DAO来实现
般情况下,EJB可以通过一个Factory对象
改变它的数据源类型。
以解决了。另外,为了支持应用能够支持多个不同的
,并在EJB的发布环境中指定这些数据源类型。在一
来得到DAO。用这种方法实现的应用,可以很容易的


  c. 要点                                                                    
  § 这个模式分离了业务逻辑和数据访问逻辑。                                    
  § 这种模式特别适用于BMP。过一段时间,这种方式同样可以移植到CMP中。    
  § DAOs可以在发布的时候选择数据源类型。                                  
  § DAOs增强了应用的可伸缩性,因为数据源改变变得很容易。                  
  § DAOs对数据访问没有任何限制,甚至可以访问XML数据。                  
  § 使用这个模式将导致增加一些额外的对象,并在一定程度上增加应用的复杂性      
 
 
  
评论】【加入收藏夹】【 】【打印】【关闭
※ 相关链接
 ·.NET和J2EE架构之战 正在升级  (2005-04-02)
 ·将J2EE平台提升到一个新的高度  (2005-04-02)
 ·Sun在开放源代码J2EE认证上又迈出  (2005-04-02)
 ·J2EE 1.4 application Server fo  (2005-04-02)
 ·《J2EE核心模式》(DAO模式)  (2005-04-02)
 ·J2EE 和 .NET之间的对比  (2005-04-02)
 ·J2EE初学者需要理解的问题  (2005-04-02)
 ·J2EE和XML为企业应用软件创造机会  (2005-04-02)
 ·J2EE相关设计模式讨论  (2005-04-02)
 ·J2EE 组件开发:消息驱动的EJB  (2005-04-02)

   栏目导行
  PHP编程
  ASP编程
  ASP.NET编程
  JAVA编程
   站点最新
·致合作伙伴的欢迎信
·媒体报道
·帝国软件合作伙伴计划协议
·DiscuzX2.5会员整合通行证发布
·帝国CMS 7.0版本功能建议收集
·帝国网站管理系统2012年授权购买说
·PHPWind8.7会员整合通行证发布
·[官方插件]帝国CMS-访问统计插件
·[官方插件]帝国CMS-sitemap插件
·[官方插件]帝国CMS内容页评论AJAX分
   类别最新
·谈谈JDBC
·JDBC专题介绍
·JDBC接口技术
·利用weblogic的POOL(连接池)连接
·Jsp中调用Oracle存储过程的小例子
·JSP数据库操作例程
·JSP数据库连接大全
·用连接池提高Servlet访问数据库的效
·一种简单JDBC连接池的实现
·数据库连接池Java实现小结
 
关于帝国 | 广告服务 | 联系我们 | 程序开发 | 网站地图 | 留言板 帝国网站管理系统