設計模式(6)-代理模式詳解(易懂)

代理模式定義

定義:爲其餘對象提供一種代理以控制對這個對象的訪問。在某些狀況下,一個對象不適合或者不能直接引用另外一個對象,而代理對象能夠在客戶端和目標對象之間起到中介的做用。程序員

image

  • Subject:抽象角色,提取的公共方法,能夠是一個接口或者抽象類
  • RealSubject:真實角色,實現具體的業務邏輯
  • Proxy:代理角色,對真實角色的邏輯處理,實現抽象角色的方法,並能夠加上本身的操做邏輯。

實例說明

代理也就是委託,我首先想到的就是遊戲代練。這個你們熟悉吧,下面就拿遊戲代練來講明一下代理模式:設計模式

1.抽象角色:也就是公共方法-玩遊戲刷級數組

public interface AbstractPlayer {
     //玩遊戲-刷級
   public void playGame();
}

2.真實角色:這裏指的是玩遊戲的人微信

public class GamePlayer implements  AbstractPlayer {
   private String name="";
   public  GamePlayer(String name){
       this.name=name;

   }
   @Override
   public void playGame() {
       Log.e("qzs","玩遊戲-刷級");
   }
}

3.代理,這裏找個遊戲代練來幫他刷級ide

public class Proxy implements AbstractPlayer {
   private  GamePlayer gamePlayer=null;

   public Proxy(GamePlayer gamePlayer){
       this.gamePlayer=gamePlayer;

   }
   @Override
   public void playGame() {
       this.gamePlayer.playGame();

   }
}

4.調用:工具

//新建一個遊戲者
         GamePlayer gamePlayer=new GamePlayer("秦子帥");
       //定義一個代練者
         Proxy proxy=new Proxy(gamePlayer);
       //玩遊戲刷級
         proxy.playGame();

image


模式結構

代理模式分爲靜態代理、動態代理。學習

靜態代理是由程序員建立或工具生成代理類的源碼,再編譯代理類。所謂靜態也就是在程序運行前就已經存在代理類的字節碼文件,代理類和委託類的關係在運行前就肯定了。this

動態代理是在實現階段不用關心代理類,而在運行階段才指定哪個對象。spa

靜態代理最基本的就是上面的實例了,下面主要講解一下動態代理,這很重要。設計


動態代理

動態代理是在實現階段不用關心代理類,而在運行階段才指定哪個對象。

首先先了解一下動態代理類

1.Interface InvocationHandler:

該接口中僅定義了一個方法Object:invoke(Object obj,Method method,Object[] args)。這個抽象方法在代理類中動態實現。

咱們來看一下invoke中的三個參數:

  • obj通常是指代理類
  • method是被代理的方法
  • args爲該方法的參數數組。

2.Proxy:

動態代理類,提供了getProxyClass (ClassLoader loader,Class[] interfaces)和newProxyInstance(ClassLoader loader,Class[] interfaces,InvocationHandler h)兩種靜態方法。

咱們來看一下newProxyInstance中的三個參數:

  • CLassLoader loader:類的加載器
  • Class<?> interfaces:指定動態代理類須要實現的全部接口
  • InvocationHandler h:獲得InvocationHandler接口的子類的實例

還拿上面的實例說:

1.創建動態代理類:

public class DynamicProxy implements InvocationHandler {
   //對真實對象的引用-被代理的實例對象
   private Object obj;

   public DynamicProxy(Object obj){
       this.obj=obj;
   }
   @Override
   public Object invoke(Object o, Method method, Object[] args) throws Throwable {
       Object result;
       //能夠加上調用方法以前的操做
       result= method.invoke(this.obj,args);
       //能夠加上調用方法以後的操做
       return result;
   }
}

2.調用:

//新建一個遊戲者
       AbstractPlayer abstractPlayer=new GamePlayer("秦子帥");

       InvocationHandler invocationHandler=new DynamicProxy(abstractPlayer);
        //類加載器
       ClassLoader classLoader=abstractPlayer.getClass().getClassLoader();
       //動態產生一個代理者
       AbstractPlayer proxy= (AbstractPlayer) Proxy.newProxyInstance(classLoader,new Class[]{AbstractPlayer.class},invocationHandler);

       proxy.playGame();

image

注意:實現動態代理的首要條件:被代理類必須實現接口。

還有一些沒有提出來,好比強制代理等等,這些你們能夠本身去寫一寫...

文章學習參考了《設計模式之禪》與網上博文
另外能夠加入個人Android技術交流羣:458739310
你們能夠關注個人微信公衆號:「安卓乾貨鋪」一個有質量、有態度的公衆號!

相關文章
相關標籤/搜索