国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
設(shè)計(jì)模式--代理模式 - 設(shè)計(jì)模式
代理模式:給某一對(duì)象提供代理對(duì)象,并由代理對(duì)象控制具體對(duì)象的引用.

代理,指的就是一個(gè)角色代表另一個(gè)角色采取行動(dòng),就象生活中,一個(gè)紅酒廠商,是不會(huì)直接把紅酒零售客戶的,都是通過代理來完成他的銷售業(yè)務(wù)的.而客戶,也不用為了喝紅酒而到處找工廠,他只要找到廠商在當(dāng)?shù)氐拇砭托辛?具體紅酒工廠在那里,客戶不用關(guān)心,代理會(huì)幫他處理.

代理模式涉及的角色:
1:抽象主題角色.聲明了代理主題和真實(shí)主題的公共接口,使任何需要真實(shí)主題的地方都能用代理主題代替.

2:代理主題角色.含有真實(shí)主題的引用,從而可以在任何時(shí)候操作真實(shí)主題,代理主題功過提供和真實(shí)主題相同的接口,使它可以隨時(shí)代替真實(shí)主題.代理主題通過持有真實(shí)主題的引用,不但可以控制真實(shí)主題的創(chuàng)建或刪除,可以在真實(shí)主題被調(diào)用前進(jìn)行攔截,或在調(diào)用后進(jìn)行某些操作.

3:真實(shí)代理對(duì)象.定義了代理角色所代表的具體對(duì)象.

下面是代理模式的實(shí)現(xiàn)類圖:


根據(jù)上圖的關(guān)系,我們可以用客戶買紅酒來模擬代理模式的實(shí)現(xiàn),

紅酒代理商和紅酒廠商都有銷售紅酒的只能,我們可以為他們定義一個(gè)共同的抽象主題角色,
Java代碼
  1. /**  
  2. *抽象主題角色,定義了真實(shí)角色和代理角色的公共接口  
  3. */  
  4. public interface SellInterface{   
  5.      public Object sell();   
  6. }  


接著,我們定義真實(shí)主題角色(這里就是紅酒工廠),它必須實(shí)現(xiàn)了SellInterface接口的.
Java代碼
  1. /**  
  2. *真實(shí)主題角色,這里指紅酒工廠角色,它實(shí)現(xiàn)了SellInterface接口  
  3. */  
  4. public class RedWineFactory implements SellInterface{   
  5.      public Object sell(){   
  6.          System.out.println("真實(shí)主題角色RedWineFactory 被調(diào)用了");   
  7.          return new Object();   
  8.      }   
  9. }  


下面是代理主題角色(這里指紅酒代理商),同樣,代理主題也必須實(shí)現(xiàn)SellInterface接口.
Java代碼
  1. /**  
  2. *代理主題角色,這里指紅酒代理商.它除了也要實(shí)現(xiàn)了sellInterface接口外,還持有紅酒  
  3. *廠商RedWineFactory 對(duì)象的引用,從而使它能在調(diào)用真實(shí)主題前后做一些必要處理.  
  4. */  
  5. public class RedWineProxy implements SellInterface{   
  6.      //持有一個(gè)RedWineFactory對(duì)象的引用   
  7.       private RedWineFactory redWineFactory;   
  8.   
  9.      //銷售總量   
  10.       private static int sell_count = 0;   
  11.   
  12.      public Object sell(){   
  13.          if(checkUser()){//在通過代理主題角色,我們可以在真實(shí)主題角色被調(diào)用前做一些諸如權(quán)限判斷的事情   
  14.              Object obj = redWineFactory.sell();   
  15.              count ++;//同樣,在調(diào)用后我們也可以執(zhí)行一些額外的動(dòng)作.   
  16.              return obj ;   
  17.          }else{   
  18.              throw new RuntimeException();   
  19.          }   
  20.      }   
  21.   
  22.      protected boolean checkUser(){   
  23.             //do something   
  24.             return true;   
  25.      }   
  26. }  


接下來看看調(diào)用代理對(duì)象的代碼
Java代碼
  1. public static void main(String agr[])   
  2. {   
  3.      SellInterface sell = new RedWineProxy();   
  4.      sell.sell();   
  5. }  


從上面的例子可以看出代理模式的工作方式,首先,因?yàn)榇碇黝}和真實(shí)主題都實(shí)現(xiàn)了共同的接口,這使我們可以在不改變?cè)瓉斫涌诘那闆r下,只要用真實(shí)主題對(duì)象的地方,都可以用代理主題來代替.其次,代理主題在客戶和真實(shí)主題之間起了一個(gè)中介作用,利用這個(gè)中介平臺(tái),我們可以在把客戶請(qǐng)求傳遞給真實(shí)主題之前,做一些必要的預(yù)處理.

java對(duì)代理模式的支持 ---動(dòng)態(tài)代理
上面的代理,我們強(qiáng)迫代理類RedWineProxy實(shí)現(xiàn)了抽象接口SellInterface.這導(dǎo)致我們的代理類無法通用于其他接口,所以不得不為每一個(gè)接口實(shí)現(xiàn)一個(gè)代理類.幸好,java為代理模式提供了支持.
java主要是通過Proxy類和InvocationHandler接口來給實(shí)現(xiàn)對(duì)代理模式的支持的.
下面用java的代理機(jī)制來實(shí)現(xiàn)上面的例子
Java代碼
  1. import java.lang.reflect.InvocationHandler;   
  2. import java.lang.reflect.Method;   
  3. import java.lang.reflect.Proxy;   
  4. /**  
  5. *代理類一定要實(shí)現(xiàn)了InvocationHandler接口  
  6. */  
  7. public class ProxyObject implements InvocationHandler{   
  8.     private Object proxy_obj;   
  9.   
  10.     ProxyObject(Object obj){   
  11.         this.proxy_obj = obj;   
  12.     }   
  13.   
  14.     public static Object factory(Object obj){   
  15.         Class cls = obj.getClass();   
  16.         //通過Proxy類的newProxyInstance方法來返回代理對(duì)象   
  17.         return Proxy.newProxyInstance(cls.getClassLoader(), cls.getInterfaces(),new ProxyObject(obj));   
  18.     }   
  19.   
  20. /**  
  21. *實(shí)現(xiàn)InvocationHandler接口的invoke  
  22. */  
  23.     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {   
  24.         System.out.println("函數(shù)調(diào)用前被攔截了:   " + method);   
  25.         if(args != null){   
  26.             //打印參數(shù)列表   
  27.             System.out.println("方法有  " + args.length + "    個(gè)參數(shù)");   
  28.             for(int i = 0; i < args.length; i ++){   
  29.                 System.out.println(args[i]);   
  30.             }   
  31.         }   
  32.         //利用反射機(jī)制動(dòng)態(tài)調(diào)用原對(duì)象的方法   
  33.          Object mo = method.invoke(proxy_obj, args);   
  34.         System.out.println("函數(shù)調(diào)用后進(jìn)行處理 :   " + method);   
  35.         return mo;   
  36.     }   
  37.   
  38.     //測(cè)試代碼       
  39.     public static void main(String agr[]){   
  40.         SellInterface si = (SellInterface)factory(new RedWineFactory());   
  41.         si.sell();   
  42.     }   
  43. }  

通過上面的代碼可以看出,代理主題ProxyObject類并沒有實(shí)現(xiàn)我們定義的SellInterface借口,
而是實(shí)現(xiàn)了java的InvocationHandler接口,這樣就把代理主題角色和我們的業(yè)務(wù)代碼分離開來,使代理對(duì)象能通用于其他接口.
其實(shí)InvocationHandler接口就是一種攔截機(jī)制,當(dāng)系統(tǒng)中有了代理對(duì)象以后,對(duì)原對(duì)象(真實(shí)主題)方法的調(diào)用,都會(huì)轉(zhuǎn)由InvocationHandler接口來處理,并把方法信息以參數(shù)的形式傳遞給invoke方法,這樣,我們就可以在invoke方法中攔截原對(duì)象的調(diào)用,并通過反射機(jī)制來動(dòng)態(tài)調(diào)用原對(duì)象的方法.這好象也是spring aop編程的基礎(chǔ)吧

接著,用代理模式實(shí)現(xiàn)一個(gè)超級(jí)簡(jiǎn)單的aop攔截機(jī)制
這個(gè)例子可以攔截我們指定的函數(shù),并在攔截前后根據(jù)需要進(jìn)行處理
Java代碼
  1. /**  
  2. *切面接口,通過實(shí)現(xiàn)這個(gè)接口,我們可以對(duì)指定函數(shù)在調(diào)用前后進(jìn)行處理  
  3. */  
  4. public interface AopInterface {   
  5.    public void before(Object obj);//調(diào)用的處理   
  6.    public void end(Object obj);//調(diào)用后的處理   
  7. }  


這個(gè)是實(shí)現(xiàn)了AopInterface 接口,在這里我們實(shí)現(xiàn)了我們的處理邏輯
Java代碼
  1. public class AopInterfaceImp implements AopInterface{   
  2.   
  3.     public void before(Object obj) {   
  4.         System.out.println("調(diào)用前攔截");   
  5.     }   
  6.   
  7.     public void end(Object obj) {   
  8.         System.out.println("調(diào)用調(diào)用后處理");   
  9.     }   
  10.   
  11. }  


接著是代理類
Java代碼
  1. public class PeoxyObject implements InvocationHandler {   
  2.     private AopInterface aop;//定義了切入時(shí)調(diào)用的方法   
  3.     private Object proxy_obj;   
  4.     private String methodName;//指定要切入的方法名   
  5.   
  6.     PeoxyObject(){}   
  7.   
  8.     public Object factory(Object obj){   
  9.         proxy_obj = obj;   
  10.         Class cls = obj.getClass();   
  11.         return Proxy.newProxyInstance(cls.getClassLoader(), cls.getInterfaces(),this);   
  12.     }   
  13.   
  14.     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {   
  15.         if(this.aop == null)throw new NullPointerException("aop is null");   
  16.         if(method == null)throw new NullPointerException("method is null");   
  17.   
  18.         Object o;   
  19. //如果指定了要攔截方法名,并且調(diào)用的方法和指定的方法名相同,則進(jìn)行攔截處理   
  20. //否則當(dāng)正常方法處理   
  21.         if(methodName != null && method.toString().indexOf(methodName) != -1){   
  22.             aop.before(proxy_obj);//指定方法調(diào)用前的處理   
  23.             o = method.invoke(proxy_obj, args);   
  24.             aop.end(proxy_obj);//指定方法調(diào)用后的處理   
  25.         }else{   
  26.             //沒有指定的方法,以正常方法調(diào)用   
  27.             o = method.invoke(proxy_obj, args);   
  28.         }   
  29.         return o;   
  30.     }   
  31.   
  32.     public AopInterface getAop() {   
  33.         return aop;   
  34.     }   
  35.   
  36.     public void setAop(AopInterface aop) {   
  37.         this.aop = aop;   
  38.     }   
  39.   
  40.     public String getMethodName() {   
  41.         return methodName;   
  42.     }   
  43.   
  44.     public void setMethodName(String methodName) {   
  45.         this.methodName = methodName;   
  46.     }   
  47. }  


這里定義一個(gè)用來測(cè)試用的類
Java代碼
  1. public interface SubInterface {   
  2.     public void add(String value1,String value2);   
  3.     public void acc(String value1);   
  4. }   
  5.   
  6. public class ImpObject implements SubInterface{   
  7.   
  8.     public void add(String value1,String value2) {   
  9.         System.out.println("ImpObject add(String value1,String value2)");   
  10.     }   
  11.   
  12.     public void acc(String value1){   
  13.         System.out.println("ImpObject acc(String value1)");   
  14.     }   
  15.   
  16. }  


這里是測(cè)試代碼
Java代碼
  1. public static void main(String agr[]){   
  2.      PeoxyObject po = new PeoxyObject();   
  3.   
  4.      po.setAop(new AopInterfaceImp());//我們實(shí)現(xiàn)的攔截處理對(duì)象   
  5.       po.setMethodName("acc");//指定要攔截的函數(shù)   
  6.         
  7.       SubInterface si = (SubInterface)po.factory(new ImpObject());   
  8.    //因?yàn)閍dd方法不是我們指定的攔截函數(shù),AopInterfaceImp是不會(huì)被執(zhí)行   
  9.       si.add("tt","dd");      
  10.   
  11.    //acc是我們指定的攔截方法,所以調(diào)用acc的前后會(huì)先執(zhí)行AopInterfaceImp   
  12.     //對(duì)象的兩個(gè)方法   
  13.       si.acc("tt");   
  14.  }  


通過上面可以看出,攔截機(jī)制是代理模式的重要使用方式之一,
除了攔截,代理模式還常用于資源加載,當(dāng)我們要加載的資源很大時(shí),我們可以讓真實(shí)主題角色在后臺(tái)加載資源,讓代理主題角色負(fù)責(zé)處理前臺(tái)的等待提示信息.
還有就是授權(quán)機(jī)制,通過代理能攔截真實(shí)主題的能力,來控制真實(shí)主題的訪問權(quán)限.
本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
java反射機(jī)制與動(dòng)態(tài)代理(三)
關(guān)于java的動(dòng)態(tài)代理
Design Pattern: delegation
java動(dòng)態(tài)代理
設(shè)計(jì)模式之代理模式(proxy pattern)
Spring的cglib代理!(給類生成子類)
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服