2,監護過程:有了監護人,寶寶就比較安全了,若是誰想和寶寶一塊兒玩就須要先找到監護人,通過監護人贊成才能夠和寶寶一塊兒玩。html
還好比過年了,寶寶收到不少壓歲錢,須要把錢存到銀行,就須要父母幫忙才能夠。java
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) Remote Proxy能夠隱藏一個對象存在於不一樣地址空間的事實。也使得客戶端能夠訪問在遠程機器上的對象,遠程機器可能具備更好的計算性能與處理速度,能夠快速響應並處理客戶端請求。
2) Virtual Proxy 能夠進行最優化,例如根據要求建立對象。即經過使用一個小對象來表明一個大對象,能夠減小系統資源的消耗。
3) Protection Proxies和Smart Reference都容許在訪問一個對象時有一些附加的內務處理(Housekeeping task) 。優化
Proxy模式還能夠對用戶隱藏另外一種稱之爲寫時複製(copy-on-write)的優化方式,該優化與根據須要建立對象有關。拷貝一個龐大而複雜的對象是一種開銷很大的操做,若是這個拷貝根本沒有被修改,那麼這些開銷就沒有必要。用代理延遲這一拷貝過程,咱們能夠保證只有當這個對象被修改的時候纔對它進行拷貝。在實現copy-on-write時必須對實體進行引用計數。拷貝代理僅會增長引用計數。只有當用戶請求一個修改該實體的操做時,代理纔會真正的拷貝它。在這種狀況下,代理還必須減
少實體的引用計數。當引用的數目爲零時,這個實體將被刪除。copy-on-write能夠大幅度的下降拷貝龐大實體時的開銷。ui
代理模式可以協調調用者和被調用者,在必定程度上下降了系統的耦合度。this
因爲在客戶端和真實主題之間增長了代理對象,所以有些類型的代理模式可能會形成請求的處理速度變慢。
實現代理模式須要額外的工做,有些代理模式的實現很是複雜。編碼
示例程序:
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; }
參考資料 :