代理模式——動態代理和模板方法那點事
阿新 • • 發佈:2019-02-18
上篇我們將了一下代理模式的靜態代理,然後碰到一個程式碼重複的問題。
回頭在來看下我們用代理實現事務的封裝,它們都遵循這樣的一個結構:
System.out.println("------獲取連線------");
System.out.println("------開戶事務------");
方法呼叫
System.out.println("------提交事務------");
System.out.println("------關閉連線------");
下面我們就再來回想一個叫做模板方法的設計模式吧。這個設計模式有兩種用途:封裝演算法步驟和提取公共部分。現在我們要用的是這個設計模式的提取公共部分。PS:比較可惜的是,我看原始碼沒有搞明白代理這塊的具體實現,只是按照個人對設計模式的一種理解來分析一下而已。
這些結構不只是上面的形式,還有方法名、引數、返回值,每個類都有實現的介面。
個人對動態代理的理解就是用了一個模板方法來進行的實現,提取一個公共的InvocationHandler介面,這個介面中有一個invoke方法,方法的引數分別是Proxy,Method,args。通過Method可以獲取到要執行的方法,也就是把需要變更的東西都進行了抽取。
這樣,就實現了變更的抽取,那麼只需要通過method.invoke()方法,就可以調取需要呼叫的方法。而公共部分的操作,就只需要些一份就足夠了。
下面是程式碼實現,介面和BLL實現類,沿用上篇提到的使用代理後的BLLImpl:
現在,關於事務的程式碼,只需要維護一份就足夠了。public class TransactionHandler implements InvocationHandler { private Object targetObject; public Object newProxyInstance(Object targetObject){ this.targetObject=targetObject; return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(), targetObject.getClass().getInterfaces(), this); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object ret=null; System.out.println("------獲取連線------"); System.out.println("------開戶事務------"); ret=method.invoke(targetObject, args); System.out.println("------提交事務------"); System.out.println("------關閉連線------"); return ret; } }
關於模板方法的另一個應用——封裝演算法步驟,Servlet就是一個很好的例子,有興趣可以自己看一下究竟怎樣封裝演算法就是用到了模板方法模式。
知道設計模式是一回事,可以應用又是一回事,能夠在設計的時候想到設計模式是一件任重而道遠的事情。
一款好的軟體,一個大的架構,必定是N多個設計模式的結合,三層架構如此,MVC架構也如此。本人關於MVC和三層架構曾經寫過一篇博文進行對比,學這塊的時候又回頭看了一下,就現在而言,當時的理解還是沒有太大問題的,博文名稱是:詳談架構。