欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
別裝了-第一集:代理模式、動(dòng)態(tài)代理和面向方面 - 別裝了!大家一起來(lái)魯棒啦!-loobong - JavaEye技術(shù)網(wǎng)站
Java代碼
  1. Public class ViewAction implements Action  
  2. {  
  3.         public void doAction()  
  4.         {  
  5.                //做View的動(dòng)作  
  6.                System.out.println(“You could view the information……”);  
  7.                ……  
  8. }  
  9. }  

代理的意思很好理解,它借鑒了我們日常所用的代理的意思:就是本來(lái)該自己親自去做的某件事,由于某種原因不能直接做,而只能請人代替你做,這個(gè)被你請來(lái)做事的人就是代理。比如過(guò)春節要回家,由于你要上班,沒(méi)時(shí)間去買(mǎi)票,就得票務(wù)中介代你購買(mǎi),這就是一種代理模式。這個(gè)情景可以形象的描述如下:

Java代碼
  1. class:火車(chē)站  
  2. {  
  3.         賣(mài)票:  
  4.        {……}  
  5. }  

 

火車(chē)站是賣(mài)票的地方,我們假設只能在火車(chē)站買(mǎi)到票。賣(mài)票的動(dòng)作實(shí)質(zhì)是火車(chē)站類(lèi)完成的。

Java代碼
  1. Class:票務(wù)中介  
  2. {  
  3.         賣(mài)票:  
  4.         {  
  5.                收中介費;  
  6.               火車(chē)站.賣(mài)票;  
  7. }  
  8. }  

 

 顧客找票務(wù)中介買(mǎi)票的時(shí)候,調用票務(wù)中介.賣(mài)票。票務(wù)中介其實(shí)做了兩件事,一是去火車(chē)站買(mǎi)票,二是不能白幫你賣(mài)票,肯定要收中介費。而你得到的好處是不用直接去火車(chē)站買(mǎi)票,節省了買(mǎi)票的時(shí)間用來(lái)上班。     以上我們簡(jiǎn)單模擬了代理模式的情景和為什么要使用代理模式,下面我們以一個(gè)例子來(lái)具體分析一下JAVA中的代理模式。     假設有一個(gè)信息管理系統,用些用戶(hù)有瀏覽信息的權限,有些用戶(hù)有瀏覽、添加和修改信息的權限,還有些用戶(hù)有除了上述的權限,還有刪除信息的權限,那么我們最容易想到的做法如下:
Java代碼
  1. public class ViewAction  
  2. {  
  3.         //由userId計算權限  
  4.         ……  
  5.         String permission = ……;  
  6.        if(permission.equals(Constants.VIEW))  
  7.         {  
  8.                System.out.println(“You could view the information……”);  
  9.                ……  
  10. }  
  11. }  
  其他的動(dòng)作都和瀏覽信息的動(dòng)作差不多。我們來(lái)看這樣的類(lèi),很容易看出它的一些缺點(diǎn)來(lái):第一、它把權限計算和動(dòng)作執行都放在一個(gè)類(lèi)里,兩者的功能相互混在一起,容易造成思路的混亂,而且修改維護和測試都不好;一句話(huà)來(lái)說(shuō), 它不滿(mǎn)足單一職責原則 。第二是客戶(hù)調用的時(shí)候 依賴(lài)具體的類(lèi),造成擴展和運行期內的調用的困難,不滿(mǎn)足依賴(lài)顛倒原則 ( 依賴(lài)倒轉原則(DIP)盡量依賴(lài) 抽象, 定義一個(gè)接口去實(shí)現它, 不要依賴(lài) 具體 ) 。

    既然有這么多的問(wèn)題,我們有必要對該類(lèi)進(jìn)行重新設計。其實(shí)大家早已想到,這個(gè)類(lèi)應該使用代理模式。是啊,和我們買(mǎi)火車(chē)票的動(dòng)作一樣,動(dòng)作類(lèi)不能直接執行那個(gè)動(dòng)作,而是要先檢查權限,然后才能執行;先檢查權限,后執行的那各類(lèi)其實(shí)就是一個(gè)代理類(lèi),修改后的代碼如下:

Java代碼
  1. public interface Action  
  2. {  
  3.         public void doAction();  
  4. }  

 

首先是設計一個(gè)接口,用來(lái)滿(mǎn)足依賴(lài)顛倒原則。

Java代碼
  1. Public class ViewAction implements Action  
  2. {  
  3.         public void doAction()  
  4.         {  
  5.                //做View的動(dòng)作  
  6.                System.out.println(“You could view the information……”);  
  7.                ……  
  8. }  
  9. }  

 

    這個(gè)類(lèi)跟火車(chē)站一樣,是動(dòng)作的真實(shí)執行者。
Java代碼
  1. Public class ProxyViewAction implements Action  
  2. {  
  3.         private Action action = new ViewAction();  
  4.         public void doAction()  
  5.         {  
  6.                //調用權限類(lèi)的方法取得用戶(hù)權限  
  7.                if(Permission.getPermission(userId).equals(Constants.VIEW))  
  8.                {  
  9.                       action.doAction();  
  10. }  
  11. }  
  12. }  
  這是代理類(lèi),很容易理解。在我們的ProxyViewAction類(lèi)中,除了做了客戶(hù)真正想要做的動(dòng)作:doAction()以外,還進(jìn)行了 額外 的動(dòng)作檢查用戶(hù)的權限。而作核心動(dòng)作doAction()是在一個(gè) 干干凈凈 的類(lèi):ViewAction中進(jìn)行,這個(gè)類(lèi)只做 核心動(dòng)作 ,對其他的不關(guān)心,滿(mǎn)足了單一職責原則。      客戶(hù)端通過(guò)調用代理類(lèi)來(lái)執行動(dòng)作 ,而代理類(lèi)一是將權限判斷和動(dòng)作的執行分離開(kāi)來(lái),滿(mǎn)足了單一職責原則;二是實(shí)現了 一個(gè)接口,從而滿(mǎn)足了依賴(lài)顛倒原則。比第一個(gè)思路好了很多。     代理又被稱(chēng)為 委派 ,說(shuō)的是代理類(lèi) 并不真正的執行那個(gè)核心動(dòng)作 ,而是委派給另外一個(gè)類(lèi)去執行,如ProxyView類(lèi)中,ProxyView類(lèi)并沒(méi)有真正執行doAction()方法,而是交給ViewAction類(lèi)去執行。     我們再來(lái)看代理類(lèi)ProxyViewAction,可以看到它不僅依賴(lài)于接口A(yíng)ction,而且依賴(lài)于具體的實(shí)現ViewAction。這樣對我們的系統擴展很不利,比如我們有Add動(dòng)作、Delete動(dòng)作、Modify動(dòng)作等等,我們需要對每一個(gè)動(dòng)作都寫(xiě)一個(gè)代理類(lèi),而這些代理類(lèi)都做同樣的事情,先進(jìn)行權限判斷,然后再委派。所以我們需要對這些代理再進(jìn)行一次抽象, 讓它只依賴(lài)接口A(yíng)ction,而不依賴(lài)于具體的實(shí)現 。

    要實(shí)現這樣的想法,我們需要將代理類(lèi)中的具體實(shí)現提走,讓代理的使用者在運行期提供具體的實(shí)現類(lèi),即所謂的 依賴(lài)注入 ,如下:

Java代碼
  1. Public class ProxyAction implements Action  
  2. {  
  3.         private Action action;  
  4.         public ProxyAction(Action action)  
  5.         {  
  6.                this.action = action;  
  7. }  
  8.         public void doAction()  
  9.         {  
  10.                //調用權限類(lèi)的方法取得用戶(hù)權限  
  11.                if(Permission.getPermission(userId).equals(action.getClass().getName()))  
  12.                {  
  13.                       action.doAction();  
  14. }  
  15. }  
  16. }  

 

這樣,我們就將所有實(shí)現了Action接口的實(shí)現使用一個(gè)代理類(lèi)來(lái)代理它們。除了ViewAction類(lèi)能用,以后擴展的AddAction、       ModifyAction、DeleteAction類(lèi)等等,都可以使用一個(gè)代理類(lèi):ProxyAction。     而我們的客戶(hù)端類(lèi)似如下: Action action = ProxyAction(new ViewAction); Action.doAction();     通過(guò)對代理類(lèi)的 依賴(lài)注入 ,我們使得代理類(lèi)初步有了一定擴展性。但是我們還要看到,這個(gè)代理類(lèi)依賴(lài)于某一個(gè)確定的接口。這仍然不能滿(mǎn)足我們的實(shí)際要求,如我們的系統的權限控制一般是整個(gè)系統級的,這樣系統級的權限控制,我們很難在整個(gè)系統里抽象出一個(gè)統一的接口,可能會(huì )有多個(gè)接口,按照上面的代理模式,我們需要對每一個(gè)接口寫(xiě)一個(gè)代理類(lèi),同樣,這些類(lèi)的功能都是一樣的。這顯然不是一個(gè)好地解決辦法。     基于上面的原因,我們需要解決一個(gè)系統在沒(méi)有統一的接口的情況下,對一些零散的對象的某一些動(dòng)作使用代理模式的問(wèn)題。JAVA API為我們引入了動(dòng)態(tài)代理或動(dòng)態(tài)委派的技術(shù)。     動(dòng)態(tài)代理的核心是 InvocationHandler接口 ,要使用動(dòng)態(tài)代理就必須實(shí)現該接口。這個(gè)接口的委派任務(wù)是在invoke(Object proxy, Method m, Object[] args)方法里面實(shí)現的: //invoke是調用的意思 //在調用核心功能之前作一些動(dòng)作 …… //調用核心功能 m.invoke(obj, args); //在調用核心功能以后做一些動(dòng)作 ……     我們可以看到動(dòng)態(tài)代理其實(shí)用的是 反射機制 來(lái)調用核心功能的:m.invoke(obj, args);正是這種反射機制的使用使得我們調用核心功能更加靈活,而 不用依賴(lài)于某一個(gè)具體的接口,而是依賴(lài)于Object對象 。

    下面我們來(lái)具體看看動(dòng)態(tài)代理或動(dòng)態(tài)委派如何使用:

Java代碼
  1. public class ProxyAction implements InvocationHandler {  
  2. private Object action;  
  3. //構造方法  
  4. public ProxyAction(Object action)  
  5. {  
  6.        this.action = action;  
  7. }  
  8. public static Object getInstance(Object action)  
  9. {  
  10.         return Proxy.newProxyInstance(action.getClass().getClassLoader(),  
  11. action.getClass().getInterfaces(),new ProxyAction(action));  
  12. }  
  13.    
  14. public Object invoke(Object proxy, Method m, Object[] args)  
  15.                throws Throwable {  
  16.           
  17.         Object result;  
  18.    
  19.        try {  
  20.                       //在委派之前作動(dòng)作,如權限判斷等  
  21.            System.out.println("before method " + m.getName());  
  22.                       //進(jìn)行委派  
  23.            result = m.invoke(action, args);  
  24.    
  25.        } catch (InvocationTargetException e) {  
  26.    
  27.            throw e.getTargetException();  
  28.    
  29.        } catch (Exception e) {  
  30.    
  31.            throw new RuntimeException("unexpected invocation exception: "  
  32.    
  33.                   + e.getMessage());  
  34.    
  35.        } finally {  
  36.                       //在委派之后做動(dòng)作  
  37.            System.out.println("after method " + m.getName());  
  38.    
  39.        }  
  40.    
  41.        return result;  
  42.    
  43.    
  44. }  
  45.    
  46. }  

 

這個(gè)代理類(lèi),首先是實(shí)現了InvocationHandler接口;然后在getInstance()方法里得到了代理類(lèi)的實(shí)例;在invoke()方法里實(shí)現代理功能,也很簡(jiǎn)單。     下面我們來(lái)看客戶(hù)端: Action action = (Action)ProxyAction.getInstance(new ViewAction()); Action.doAction();     我們可以看到代理類(lèi)對接口的依賴(lài)也轉移到了客戶(hù)端上,這樣,代理類(lèi)不依賴(lài)于某個(gè)接口。對于同樣的代理類(lèi)ProxyAction,我們也可以有如下的客戶(hù)端調用: Engine engine = (Engine)ProxyAction.getInstance(new EngineImpl()); Engine.execute();     只要engineImpl類(lèi)實(shí)現了Engine接口,就可以像上面那樣使用。

    現在我們可以看到,動(dòng)態(tài)代理的確是擁有相當的靈活性。但我們同時(shí)也看到了,這個(gè)代理類(lèi)寫(xiě)起來(lái)比較麻煩,而且也差不多每次都寫(xiě)這樣千篇一律的東西,只有委派前的動(dòng)作和委派后的動(dòng)作在不同的代理里有著(zhù)不同,其他的東西都需要照寫(xiě)。如果這樣的代理類(lèi)寫(xiě)多了,也會(huì )有一些冗余代理。需要我們進(jìn)一步優(yōu)化,這里我們使用模板方法模式來(lái)對這個(gè)代理類(lèi)進(jìn)行優(yōu)化,如下:

Java代碼
  1. public abstract class BaseProxy implements InvocationHandler {  
  2. private Object obj;  
  3. protected BaseProxy(Object obj)  
  4. {  
  5.        this.obj = obj;  
  6. }  
  7. public static Object getInstance(Object obj,InvocationHandler instance)  
  8. {  
  9.         return Proxy.newProxyInstance(obj.getClass().getClassLoader(),  
  10. obj.getClass().getInterfaces(),instance);  
  11. }  
  12.    
  13. public Object invoke(Object proxy, Method m, Object[] args)  
  14.                throws Throwable {  
  15.         // TODO Auto-generated method stub  
  16.         Object result;  
  17.    
  18.        try {  
  19.    
  20.            System.out.println("before method " + m.getName());  
  21.            this.doBegin();  
  22.    
  23.            result = m.invoke(obj, args);  
  24.    
  25.        } catch (InvocationTargetException e) {  
  26.    
  27.            throw e.getTargetException();  
  28.    
  29.        } catch (Exception e) {  
  30.    
  31.            throw new RuntimeException("unexpected invocation exception: "  
  32.    
  33.                   + e.getMessage());  
  34.    
  35.        } finally {  
  36.    
  37.            System.out.println("after method " + m.getName());  
  38.            this.doAfter();  
  39.    
  40.        }  
  41.    
  42.        return result;  
  43.    
  44.    
  45. }  
  46. public abstract void doBegin();  
  47. public abstract void doAfter();  
  48.    
  49. }  
 

這樣,代理的實(shí)現類(lèi)只需要關(guān)注實(shí)現委派前的動(dòng)作和委派后的動(dòng)作就行,如下

Java代碼
  1. public class ProxyImpl extends BaseProxy {  
  2. protected ProxyImpl(Object o)  
  3. {  
  4.        super(o);  
  5. }  
  6. public static Object getInstance(Object foo)  
  7. {  
  8.         return getInstance(foo,new ProxyImpl(foo));  
  9. }  
  10.    
  11. //委派前的動(dòng)作  
  12. public void doBegin() {  
  13.         // TODO Auto-generated method stub  
  14.        System.out.println("begin doing....haha");  
  15.    
  16. }  
  17.    
  18. //委派后的動(dòng)作  
  19. public void doAfter() {  
  20.         // TODO Auto-generated method stub  
  21.        System.out.println("after doing.....yeah");  
  22.    
  23. }  
  24.    
  25. }  

 

從上面的代碼,我們可以看出代理實(shí)現類(lèi)的確是簡(jiǎn)單多了,只關(guān)注了委派前和委派后的動(dòng)作,這是我們作為一個(gè)代理真正需要關(guān)心的。     至此,代理模式和動(dòng)態(tài)代理已經(jīng)告一段落。我們將動(dòng)態(tài)代理引申一點(diǎn)說(shuō)開(kāi)去,來(lái)作為這篇文章的蛇足。     這個(gè)話(huà)題就是面向方面的編程,或者說(shuō)AOP。我們看上面的ProxyImpl類(lèi),它的兩個(gè)方法doBegin()和doAfter(),這是做核心動(dòng)作之前和之后的兩個(gè)截取段。正是這兩個(gè)截取段,卻是我們AOP的基礎。在OOP里,doBegin(),核心動(dòng)作,doAfter()這三個(gè)動(dòng)作在多個(gè)類(lèi)里始終在一起,但他們所要完成的邏輯卻是不同的,如doBegin()可能做的是權限,在所有的類(lèi)里它都做權限;而在每個(gè)類(lèi)里核心動(dòng)作卻各不相同;doAfter()可能做的是日志,在所有的類(lèi)里它都做日志。正是因為在所有的類(lèi)里,doBegin()或doAfter()都做的是同樣的邏輯,因此我們需要將它們提取出來(lái),單獨分析、設計和編碼,這就是我們的AOP的思想。     這樣說(shuō)來(lái),我們的動(dòng)態(tài)代理就能作為實(shí)現AOP的基礎了。好了,就說(shuō)這么多,關(guān)于A(yíng)OP技術(shù),我們可以去關(guān)注關(guān)于這方面的知識。
本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
代理模式、動(dòng)態(tài)代理和面向方面(AOP)
java反射機制與動(dòng)態(tài)代理(三)
java的動(dòng)態(tài)代理模式簡(jiǎn)單實(shí)例
Spring AOP 本質(zhì)系列之動(dòng)態(tài)代理
設計模式--代理模式 - 設計模式
Design Pattern: delegation
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久