1. 簡介
代理模式(Proxy Pattern)是GoF 23種Java常用設計模式之一。代理模式的定義:Provide a surrogate or placeholder for another object to controlaccess to it(爲其他對象提供一種代理以控制對這個對象的訪問)。使用代理模式創建代理對象,讓代理對象控制目標對象的訪問(目標對象可以是遠程的對象、創建開銷大的對象或需要安全控制的對象),並且可以在不改變目標對象的情況下添加一些額外的功能。
2. UML類圖
3. 模式中包含的角色及其職責
Subject:抽象主題角色,抽象主題類可以是抽象類,也可以是接口,是一個最普通的業務類型定義,無特殊要求。
RealSubject:具體主題角色,也叫被委託角色、被代理角色。是業務邏輯的具體執行者。
Proxy:代理主題角色,也叫委託類、代理類。它把所有抽象主題類定義的方法給具體主題角色實現,並且在具體主題角色處理完畢前後做預處理和善後工作。(最簡單的比如打印日誌)
4. 代碼實現
(1) Subject
package com.jackie.designpatterns.proxy;
/**
* 抽象主題,定義主要功能
*/
publicinterface Subject {
publicvoid operate();
}
(2) RealSubject
package com.jackie.designpatterns.proxy;
/**
* 具體主題
*/
publicclass RealSubject implements Subject{
@Override
publicvoid operate() {
System.out.println("realsubject operatestarted......");
}
}
(3) Proxy
package com.jackie.designpatterns.proxy;
/**
* 代理類
*/
publicclass Proxy implements Subject{
private Subject subject;
public Proxy(Subject subject) {
this.subject = subject;
}
@Override
publicvoid operate() {
System.out.println("before operate......");
subject.operate();
System.out.println("after operate......");
}
}
(4) Client
package com.jackie.designpatterns.proxy;
/**
* 客戶
*/
publicclass Client {
/**
* @param args
*/
publicstaticvoid main(String[] args) {
Subject subject = new RealSubject();
Proxy proxy = new Proxy(subject);
proxy.operate();
}
}
運行結果: beforeoperate……
realsubject operate started……
afteroperate……
5. 應用場景
現實世界中,祕書就相當於一個代理,老闆開會,那麼通知員工開會時間、佈置會場、會後整理會場等等開會相關工作就可以交給祕書做,老闆就只需要開會就行了,不需要親自做那些事。同理,在我們程序設計中也可使用代理模式來將由一系列無關邏輯組合在一起的代碼進行解耦合,比如業務代碼中的日誌代碼就可以在代理中進行。Spring的AOP就是典型的動態代理應用。
6. 代理模式的應用形式
(1)遠程代理(Remote Proxy) -可以隱藏一個對象存在於不同地址空間的事實。也使得客戶端可以訪問在遠程機器上的對象,遠程機器可能具有更好的計算性能與處理速度,可以快速響應並處理客戶端請求。
(2)虛擬代理(Virtual Proxy) – 允許內存開銷較大的對象在需要的時候創建。只有我們真正需要這個對象的時候才創建。
(3)寫入時複製代理(Copy-On-Write Proxy) – 用來控制對象的複製,方法是延遲對象的複製,直到客戶真的需要爲止。是虛擬代理的一個變體。
(4)保護代理(Protection (Access)Proxy) – 爲不同的客戶提供不同級別的目標對象訪問權限
(5)緩存代理(Cache Proxy) – 爲開銷大的運算結果提供暫時存儲,它允許多個客戶共享結果,以減少計算或網絡延遲。
(6)防火牆代理(Firewall Proxy) – 控制網絡資源的訪問,保護主題免於惡意客戶的侵害。
(7)同步代理(SynchronizationProxy) – 在多線程的情況下爲主題提供安全的訪問。
(8)智能引用代理(Smart ReferenceProxy) - 當一個對象被引用時,提供一些額外的操作,比如將對此對象調用的次數記錄下來等。
(9)複雜隱藏代理(Complexity HidingProxy) – 用來隱藏一個類的複雜集合的複雜度,並進行訪問控制。有時候也稱爲外觀代理(Façade Proxy),這不難理解。複雜隱藏代理和外觀模式是不一樣的,因爲代理控制訪問,而外觀模式是不一樣的,因爲代理控制訪問,而外觀模式只提供另一組接口。