熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java高級技術 >> 正文

J2EE中幾種業務代理模式的實現和比較

2022-06-13   來源: Java高級技術 

  什麼是業務代理模式(buiness proxy)?
  
  在JEE系統中一般劃分為表現層和業務邏輯層為實現表現層和業務邏輯層之間的最大限度解耦引入業務代理模式這樣當表現層或業務邏輯層具體實現技術發生時對彼此的影響很小當然如果希望實現完全解耦我們可以使用消息系統JMS來實現本文章只討論同步系統范疇
  
  以一個Struts+Hibernate為例以下代碼是Struts的Action實現方法代碼
  
  public ActionForward update(ActionMapping mapping
  ActionForm form
  HttpServletRequest request
  HttpServletResponse response) throws Exception {
  EgForm egForm = (EgForm) form;
  //直接調用Hiberante實現數據持久化
  getUser(request)setName(egFormgetName());
  return mappingfindForward(SUCCESS);
  }
  
  上述update方法代碼中直接調用了後台數據庫操作帶來的缺點是緊密的耦合性當更新用戶資料的需要有更多變化時將會直接在update中加入更多業務邏輯代碼也就是說我們的業務邏輯層代碼已經完全依賴Struts這個表現層技術萬一以後我們選用其它表現層技術替代Struts後將會觸及我們業務邏輯層代碼
  
  修改後代碼如下
  
  public ActionForward update(ActionMapping mapping
  ActionForm form
  HttpServletRequest request
  HttpServletResponse response) throws Exception {
  EgForm egForm = (EgForm) form;
  Contact contact = new Contact();
  pyProperties(contact egForm);
  
  UserService userService = ServiceFactorycreate();
  userServiceupdate(contact);
  return mappingfindForward(SUCCESS);
  }
  
  上述修改後代碼中我們將業務邏輯包裝在UserService的一個子類中實現作為客戶端我們使用工廠模式創建UserService對象這樣的好處是我們不必在update方法中耦合UserService的具體子類也許UserService的子類是UserServiceHibernate或UserServiceEJB等
  
  使用工廠模式實現了表現層和業務層的解耦這是早期很多系統的架構實現但是這樣還是帶來很多問題我們下面比較一下幾種實現方式
  
  工廠模式優缺點
  首先我們總結一下上述代碼使用了工廠模式所帶來的好處
  
 

  正如圖中所示一般使用工廠模式涉及到靜態類或單態模式如上述代碼中ServiceFactorycreate()可以使用靜態或單態模式實現從而形成客戶端單一訪問業務邏輯層入口這樣優點有兩個
  
   由於業務邏輯入口是單一的客戶端對業務邏輯訪問的可控性強例如可動態單一入口加入權限檢查或其它全局統一功能Jive中權限正是這樣實現可控性強
  
   客戶端代碼簡潔作為客戶端的表現層技術如果我們更換了實現技術修改的代碼很少例如上述代碼中如果不使用Struts更換了JSF等只要拷貝上述兩行紅字標注的代碼
  
  工廠模式帶來的主要缺點是
  
   當ServiceFactory實現子類很多時例如除了UserService外還有ProductServiceItemServiceImageService等等試圖使用一個總入口來涵括這些Service會造成過多代碼耦合在一個類中造成Facade模式濫用的後果也就是說使用工廠模式擴展性不是很強
  
   由於使用靜態或單態模式在性能上容易走入單線程單並發用戶的誤區違背了JEE多線程並發使用的原則
  
  Command模式
  Command模式可以說解決了上面工廠模式的缺點Command模式將所有的服務都展示給客戶端客戶端可以通過特定命令形式直接指定調用後台眾多Service中任何一種Petstore中Web對EJB調用就是使用了Command模式實現
  

  Command模式雖然突破了工廠模式單一入口的缺點但是帶來的缺點是易用性不夠Command模式代碼實現起來不方便這點可從Petstore繞人的WebContaollerEventAction等等眾多類中可以看出
  
  Command模式主要問題是可控性不強如果要為所有Service動態增加類似Filter等這樣通用功能如權限檢查等是非常不方便的
  
  EJB直接調用實現
  我們知道EJB是業務邏輯層實現的JEE標准技術EJB的session bean可以作為Service實現例如上面在update中調用EJB的代碼如下
  
  public ActionForward update(ActionMapping mapping
  ActionForm form
  HttpServletRequest request
  HttpServletResponse response) throws Exception {
  EgForm egForm = (EgForm) form;
  Contact contact = new Contact();
  pyProperties(contact egForm);
  
  try{
  InitialContext ic = new InitialContext();
  UserServiceLocalHome ul = iclookup(UserService);
  
  UserServiceLocal userService = ulcreate();
  userServiceupdate(contact);
  
  }catch(){
  
  }
  return mappingfindForward(SUCCESS);
  }
  
  在客戶端表現層是直接調用EJB服務的這種直接調用的方式類似Command模式但是有兩個缺點
  
   客戶端調用業務層實現代碼較多如上述紅字行數有客戶端代碼不簡潔
  
  無法非常自由地為所有Service動態增加新的Filter之類新功能當然除了EJB提供的事務機制分布集群安全ACL等除外如果你要增加這些新功能可以通過ejbjarxml配置增加
  
  業務代理模式實現目標
  總結上述兩種實現的優缺點衡量一個業務代理模式是否良好有下面幾個指標
  
   業務層所有服務完全展示給客戶端客戶端可以完全介入調用
  
   動態擴展性強可為整個業務邏輯層動態擴展新的功能
  
   客戶端調用業務層的實現代碼必須簡潔至少是可配置的最大限度降低代碼的耦合性
  
  Ioc模式/AOP實現
  目前使用Ioc模式/AOP實現業務代理能夠很好地達到上述個目標以JdonFramework為例
  
   業務層所有服務完全展示給客戶端客戶端可以完全介入調用而且調用代碼簡潔如下
  
  public ActionForward update(ActionMapping mapping
  ActionForm form
  HttpServletRequest request
  HttpServletResponse response) throws Exception {
  EgForm egForm = (EgForm) form;
  Contact contact = new Contact();
  pyProperties(contact egForm);
  
  UserService userService = WebAppUtilgetService(UserService rerquest);
  userServiceupdate(contact);
  
  return mappingfindForward(SUCCESS);
  }
  
  上述紅字兩行代碼不但適合調用普通POJO而且適合調用EJB具體是什麼可以通過jdonframeworkxml實現
  
   通過加入自己的AOP攔截器可以為整個業務邏輯層動態擴展新的功能這部分功能實現不是通過配置實現的而是使用代碼實現
  
  MethodInterceptor myI = new MyInterceptor();
  WebAppUtiladdInterceptor(myI request);
  
  有關AOP中更復雜的pointcut實現可以通過獲得Ioc容器後自己實現
  
  ContainerWrapper cw = WebAppUtilgetContainer(request);
  
  這樣可以為用戶提供非常自由的面向微容器編程的基礎這比同樣的Ioc/AOP實現Spring開源框架提供的自由度更廣更加透明
  
  更加重要的是JdonFramework只是真正紳士地完成業務代理模式不過多地介入業務層業務層相關配置是使用配置文件實現需要插入的通用功能是使用代碼實現而Spring目前版本則是將兩者混淆在一起
From:http://tw.wingwit.com/Article/program/Java/gj/201311/11153.html
    推薦文章
    Copyright © 2005-2022 電腦知識網 Computer Knowledge   All rights reserved.