漫說代理模式---給寶寶成長護航

  1. 寶寶還很小,外面的世界可不安全,如今寶寶的護航者寶寶的監護人爸爸媽媽閃亮登場。

漫說代理模式---給寶寶成長護航

2,監護過程:有了監護人,寶寶就比較安全了,若是誰想和寶寶一塊兒玩就須要先找到監護人,通過監護人贊成才能夠和寶寶一塊兒玩。html

漫說代理模式---給寶寶成長護航

還好比過年了,寶寶收到不少壓歲錢,須要把錢存到銀行,就須要父母幫忙才能夠。java

  1. 上面就用到了代理模式。

As described by GoF:緩存

"Provide a surrogate or placeholder for another object to control access over it."

UML圖以下所示:安全

漫說代理模式---給寶寶成長護航

1)代理角色(Proxy):
. 保存一個引用使得代理能夠訪問實體。若 RealSubject和Subject的接口相同,Proxy會引用Subject。
. 提供一個與Subject的接口相同的接口,這樣代理就能夠用來替代實體。
. 控制對實體的存取,並可能負責建立和刪除它。
. 其餘功能依賴於代理的類型:
• Remote Proxy負責對請求及其參數進行編碼,並向不一樣地址空間中的實體發送已編碼的請求。
• Virtual Proxy能夠緩存實體的附加信息,以便延遲對它的訪問。
• Protection Proxy檢查調用者是否具備實現一個請求所必需的訪問權限。
2) 抽象主題角色(Subject):定義真實主題角色RealSubject 和 抽象主題角色Proxy的共用接口,這樣就在任何使用RealSubject的地方均可以使
用Proxy。代理主題經過持有真實主題RealSubject的引用,不但能夠控制真實主題RealSubject的建立或刪除,能夠在真實主題RealSubject被調用前進行攔截,或在調用後進行某些操做. ide

3) 真實主題角色(RealSubject):定義了代理角色(proxy)所表明的具體對象. 性能

  1. 代理模式的應用場景

1) Remote Proxy能夠隱藏一個對象存在於不一樣地址空間的事實。也使得客戶端能夠訪問在遠程機器上的對象,遠程機器可能具備更好的計算性能與處理速度,能夠快速響應並處理客戶端請求。
2) Virtual Proxy 能夠進行最優化,例如根據要求建立對象。即經過使用一個小對象來表明一個大對象,能夠減小系統資源的消耗。
3) Protection Proxies和Smart Reference都容許在訪問一個對象時有一些附加的內務處理(Housekeeping task) 。優化

Proxy模式還能夠對用戶隱藏另外一種稱之爲寫時複製(copy-on-write)的優化方式,該優化與根據須要建立對象有關。拷貝一個龐大而複雜的對象是一種開銷很大的操做,若是這個拷貝根本沒有被修改,那麼這些開銷就沒有必要。用代理延遲這一拷貝過程,咱們能夠保證只有當這個對象被修改的時候纔對它進行拷貝。在實現copy-on-write時必須對實體進行引用計數。拷貝代理僅會增長引用計數。只有當用戶請求一個修改該實體的操做時,代理纔會真正的拷貝它。在這種狀況下,代理還必須減
少實體的引用計數。當引用的數目爲零時,這個實體將被刪除。copy-on-write能夠大幅度的下降拷貝龐大實體時的開銷。ui

代理模式可以協調調用者和被調用者,在必定程度上下降了系統的耦合度。this

代理模式的缺點

因爲在客戶端和真實主題之間增長了代理對象,所以有些類型的代理模式可能會形成請求的處理速度變慢。
實現代理模式須要額外的工做,有些代理模式的實現很是複雜。編碼

  1. 示例程序:

    JDK proxies

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
interface AnInterface {
   public void doSomething();
}
class AClass implements AnInterface {
   public void doSomething() {
      System.out.println("Inside Method AClass.doSomething()");
   }
}
public class Test {
   public static void main(String args[]) {
      AnInterface realSubject = new AClass();
      AnInterface proxy = (AnInterface)Proxy.newProxyInstance(
                        realSubject.getClass().getClassLoader(),
                        realSubject.getClass().getInterfaces(),
                        new SimpleInvocationHandler(realSubject));
      passMeAProxy(proxy);
   }
   private static void passMeAProxy(AnInterface anInterface) {
      anInterface.doSomething();
   }
}
class SimpleInvocationHandler implements InvocationHandler {
   public SimpleInvocationHandler(Object realSubject) {
      this.realSubject = realSubject;
   }
   public Object invoke(Object proxy, Method m, Object[] args){
      Object result = null;
      System.out.println("Before Calling " + m.getName());
      try {
         result = m.invoke(realSubject, args);   
      }
      catch(Exception ex) {
         System.exit(1);
      }
      System.out.println("After Calling " + m.getName());
      return result;
   }
   private Object realSubject = null;
}

參考資料 :

http://www.oodesign.com/proxy-pattern.html

http://www.javaworld.com/article/2074068/learn-java/take-control-with-the-proxy-design-pattern.html?page=2

http://blog.csdn.net/hguisu/article/details/7542143

相關文章
相關標籤/搜索