什麼是業務代理模式(buiness proxy)? 在J
EE系統中
一般劃分為表現層和業務邏輯層
為實現表現層和業務邏輯層之間的最大限度解耦
引入業務代理模式
這樣
當表現層或業務邏輯層具體實現技術發生時
對彼此的影響很小
當然
如果希望實現完全解耦
我們可以使用消息系統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();
pyProperties(contact
egForm);
UserService userService = ServiceFactory
create();
userService
update(contact);
return mapping
findForward(SUCCESS);
}
上述修改後代碼中
我們將業務邏輯包裝在UserService的一個子類中實現
作為客戶端
我們使用工廠模式創建UserService對象
這樣的好處是
我們不必在update方法中耦合UserService的具體子類
也許UserService的子類是UserServiceHibernate或UserServiceEJB等
使用工廠模式實現了表現層和業務層的解耦
這是早期很多系統的架構實現
但是這樣還是帶來很多問題
我們下面比較一下幾種實現方式
工廠模式優缺點 首先
我們總結一下上述代碼使用了工廠模式所帶來的好處
正如圖中所示
一般使用工廠模式涉及到靜態類或單態模式
如上述代碼中ServiceFactory
create()可以使用靜態或單態模式實現
從而形成客戶端單一訪問業務邏輯層入口
這樣優點有兩個
由於業務邏輯入口是單一的
客戶端對業務邏輯訪問的可控性強
例如可動態單一入口加入權限檢查或其它全局統一功能
Jive中權限正是這樣實現
可控性強
客戶端代碼簡潔
作為客戶端的表現層技術
如果我們更換了實現技術
修改的代碼很少
例如上述代碼中
如果不使用Struts更換了JSF等
只要拷貝上述兩行紅字標注的代碼
工廠模式帶來的主要缺點是
當ServiceFactory實現子類很多時
例如除了UserService外
還有ProductService
ItemService
ImageService等等
試圖使用一個總入口來涵括這些Service會造成過多代碼耦合在一個類中
造成Facade模式濫用的後果
也就是說
使用工廠模式
擴展性不是很強
由於使用靜態或單態模式
在性能上
容易走入單線程
單並發用戶的誤區
違背了J
EE多線程並發使用的原則
Command模式 Command模式可以說解決了上面工廠模式的缺點
Command模式將所有的服務都展示給客戶端
客戶端可以通過特定命令形式直接指定調用後台眾多Service中任何一種
Petstore中Web對EJB調用就是使用了Command模式實現
Command模式雖然突破了工廠模式單一入口的缺點
但是帶來的缺點是易用性不夠
Command模式代碼實現起來不方便
這點可從Petstore繞人的WebContaoller
Event
Action等等眾多類中可以看出
Command模式主要問題是可控性不強
如果要為所有Service動態增加類似Filter等這樣通用功能
如權限檢查等是非常不方便的
EJB直接調用實現 我們知道
EJB是業務邏輯層實現的J
EE標准技術
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 = ic
lookup(
UserService
);
UserServiceLocal userService = ul
create();
userService
update(contact);
}catch(){
}
return mapping
findForward(SUCCESS);
}
在客戶端表現層是直接調用EJB服務的
這種直接調用的方式類似Command模式
但是有兩個缺點
客戶端調用業務層實現代碼較多
如上述紅字行數有
行
客戶端代碼不簡潔
無法非常自由地為所有Service動態增加新的Filter之類新功能
當然除了EJB提供的事務機制
分布集群
安全ACL等除外
如果你要增加這些新功能
可以通過ejb
jar
xml配置增加
業務代理模式實現目標 總結上述兩種實現的優缺點
衡量一個業務代理模式是否良好有下面幾個指標
業務層所有服務完全展示給客戶端
客戶端可以完全介入調用
動態擴展性強
可為整個業務邏輯層動態擴展新的功能
客戶端調用業務層的實現代碼必須簡潔
至少是可配置的
最大限度降低代碼的耦合性
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 = WebAppUtil
getService(
UserService
rerquest);
userService
update(contact);
return mapping
findForward(SUCCESS);
}
上述紅字兩行代碼不但適合調用普通POJO
而且適合調用EJB
具體是什麼可以通過jdonframework
xml實現
通過加入自己的AOP攔截器可以為整個業務邏輯層動態擴展新的功能
這部分功能實現不是通過配置實現的
而是使用代碼實現
MethodInterceptor myI = new MyInterceptor();
WebAppUtil
addInterceptor(myI
request);
有關AOP中更復雜的pointcut實現
可以通過獲得Ioc容器後自己實現
ContainerWrapper cw = WebAppUtil
getContainer(request);
這樣
可以為用戶提供非常自由的面向微容器編程的基礎
這比同樣的Ioc/AOP實現Spring開源框架提供的自由度更廣
更加透明
更加重要的是
JdonFramework只是真正紳士地完成業務代理模式
不過多地介入業務層
業務層相關配置是使用配置文件實現
需要插入的通用功能是使用代碼實現
而Spring目前版本則是將兩者混淆在一起
From:http://tw.wingwit.com/Article/program/Java/gj/201311/11153.html