一、業務代理模式(buiness PRoxy)
在J2EE系統中,一般劃分為表現層和業務邏輯層,為實現表現層和業務邏輯層之間的最大限度解耦,引入業務代理模式,這樣,當表現層或業務邏輯層具體實現技術發生時,對彼此的影響很小,當然,假如希望實現完全解耦,我們可以使用消息系統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(egForm.getName()); return mapping.findForward(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();BeanUtils.copyProperties(contact, egForm); UserService userService = ServiceFactory.create(); userService.update(contact);return mapping.findForward(SUCCESS);}
正如圖中所示,一般使用工廠模式涉及到靜態類或單態模式,如上述代碼中ServiceFactory.create()可以使用靜態或單態模式實現,從而形成客戶端單一訪問業務邏輯層入口,這樣優點有兩個:
1. 由于業務邏輯入口是單一的,客戶端對業務邏輯訪問的可控性強,例如可動態單一入口加入權限檢查或其它全局統一功能。Jive中權限正是這樣實現??煽匦詮?。
2. 客戶端代碼簡潔,作為客戶端的表現層技術,假如我們更換了實現技術,修改的代碼很少,例如上述代碼中,假如不使用Struts更換了JSF等,只要拷貝上述兩行紅字標注的代碼。
工廠模式帶來的主要缺點是:
1. 當ServiceFactory實現子類很多時,例如除了UserService外,還有ProductService、ItemService、ImageService等等,試圖使用一個總入口來涵括這些Service會造成過多代碼耦合在一個類中,造成Facade模式濫用的后果。也就是說,使用工廠模式,擴展性不是很強。
2. 由于使用靜態或單態模式,在性能上,輕易走入單線程、單并發用戶的誤區,違反了J2EE多線程并發使用的原則。
二、Command模式
Command模式可以說解決了上面工廠模式的缺點,Command模式將所有的服務都展示給客戶端,客戶端可以通過特定命令形式直接指定調用后臺眾多Service中任何一種,Petstore中Web對EJB調用就是使用了Command模式實現。
Command模式雖然突破了工廠模式單一入口的缺點,但是帶來的缺點是易用性不夠,Command模式代碼實現起來不方便,這點可從Petstore繞人的WebContaoller、Event、Action等等眾多類中可以看出。
Command模式主要問題是可控性不強,假如要為所有Service動態增加類似Filter等這樣通用功能,如權限檢查等是非常不方便的。
EJB直接調用實現
我們知道,EJB是業務邏輯層實現的J2EE標準技術,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();BeanUtils.copyProperties(contact, egForm); try{InitialContext ic = new InitialContext();UserServiceLocalHome ul =ic.lookup("UserService"); UserServiceLocal userService =ul.create();userService.update(contact); }catch(){} return mapping.findForward(SUCCESS);}
新聞熱點
疑難解答