23種設計模式(7)-代理模式

worldde發表於2018-02-07

定義:

  為其他物件提供一種代理以控制對這個物件的訪問。在某些情況下,一個物件不適合或者不能直接引用另一個物件,而代理物件可以在客戶端和目標物件之間起到中介的作用

角色:

1,  抽象角色:宣告真實物件和代理物件的共同介面。

2,  代理角色:代理物件角色內部含有對真實物件的引用,從而可以操作真實物件,同時代理物件提供與真實物件相同的介面以便在任何時刻都能代替真實物件。同時,代理物件可以在執行真實物件操作時,附加其他的操作,相當於對真實物件進行封裝。

3,  真實角色:代理角色所代表的真實物件,是我們最終要引用的物件。

 

分類:

靜態代理

靜態代理也就是在程式執行前就已經存在代理類的位元組碼檔案,代理類和委託類的關係在執行前就確定了。

 

示例:

抽象角色,真實物件和代理物件共同的介面

public interface UserInfo{    
       public void queryUser ();    
       public void updateUser ();      
}
真實角色

public class UserImpl implements UserInfo{    

       @Override    
       public void queryUser() {    
           //查詢方法省略...          
       }    

       @Override    
       public void updateUser() {    
            //修改方法省略...          
       }    

}
代理角色
public class UserProxy implements UserInfo{    
   private UserInfo userImpl;    

   public AccountProxy(UserInfo userImpl) {    
       this.userImpl = userImpl;    
   }    

   @Override    
   public void queryUser() { 
         //這裡可以擴充套件,增加一些查詢之前需要執行的方法   
        //查詢方法省略...   
         //這裡可以擴充套件,增加一些查詢之後需要執行的方法         
   }    

   @Override    
   public void updateUser() {  
         //這裡可以擴充套件,增加一些修改之前需要執行的方法    
         //修改方法省略...   
         //這裡可以擴充套件,增加一些修改之後需要執行的方法         
   }  
}
使用代理之後如何呼叫他的方法?

public class Test {    
   public static void main(String[] args) {    
       UserInfo userImpl = new UserImpl();     
       UserInfo userProxy = new UserProxy(userImpl);     
             userProxy.queryUser(); 
             userProxy.updateUser();        
   }    
}

動態代理

動態代理類的原始碼是程式在執行期間由JVM根據反射等機制動態生成的,所以不存在代理類的位元組碼檔案。代理角色和真實角色的聯絡在程式執行時確定。

示例:

抽象角色,真實物件和代理物件共同的介面

public interface UserInfo{    
       public void queryUser ();    
       public void updateUser ();      
}
真實角色
public class UserImpl implementsUserInfo{    

       @Override    
       public void queryUser() {    
           //查詢方法省略...          
       }    

       @Override    
       public void updateUser() {    
            //修改方法省略...          
       }    

}
代理角色處理器:
public class UserHandler implements InvocationHandler{

         private UserInfo userImpl;
         public UserHandler(UserInfo userImpl2){
                   this.userImpl= userImpl2;
         }
         @Override
         public Object invoke(Object proxy, Method method, Object[] args) 
                                        throws Throwable {
                   Object object = null;
       //方法開始前做一些事情
       if (method.getName().equals("queryUser")) {
           object = method.invoke(userImpl, args);
            //啟用呼叫的方法   
       }
       //方法結束後做一些事情
       return object;
    }
}
如何呼叫(和靜態代理略有不同)

public class Test {         
   public static void main(String[] args) {
         UserInfo userImpl =new UserImpl();
         UserHandler handler = new UserHandler(userImpl);
         UserInfo userProxy = (UserInfo)Proxy.newProxyInstance
                      (ClassLoader.getSystemClassLoader(),
                        newClass[]{UserInfo.class}, handler);
         userProxy.queryUser();
         }
}

優點:

  業務類只需要關注業務邏輯本身,保證了業務類的重用性。這是代理的共有優點。 

   能夠協調呼叫者和被呼叫者,在一定程度上降低了系統的耦合度。

缺點:

  由於在客戶端和真實主題之間增加了代理物件,因此有些型別的代理模式可能會造成請求的處理速度變慢,例如保護代理。

         實現代理模式需要額外的工作,而且有些代理模式的實現過程較為複雜,例如遠端代理。

 


                               閒暇之餘鞏固一下自己的知識體系 ,擴充一下自己的知識面。快利用瑣碎時間給自己充電吧   !

相關文章