定義:
Provide a surrogate or placeholder for another object to control access to it.
為其他物件一種代理程式以控制對這個物件的存取。
一般說明:
一般包含的三個角色:抽象主題、特定主題、代理主題。
抽象主題:是一個抽象類別或接口,是一個普通的業務類型定義。
特定主題:業務邏輯的特定執行者
代理角色:負責對真是角色的應用,將所有抽象主題類別定義的方法限制委託給真實主題角色實現。
通用類別圖:
通用類別圖:
通用代碼:package Proxy; //抽象主题类: public interface Subject { public void doSomething(); } package Proxy; //具体主题类 public class RealSubject implements Subject{ @Override public void doSomething() { System.out.println("业务逻辑..."); } } package Proxy; //代理主题类 public class Proxy implements Subject{ private Subject sub = null; @Override public void doSomething() { this.sub.doSomething(); } public Proxy(Subject sub){ this.sub = sub; } } package Proxy; //客户端 public class Client { public static void main(String[] args) { Subject realsub = new RealSubject(); Subject proxy = new Proxy(realsub); proxy.doSomething(); } }優點: 1. 職責清晰 特定主題類對高層透明,在代理主題類別中建構特定主題類別程式碼實作:
package GeneralProxy; public interface Subject { public void doSomething(); } package GeneralProxy; public class RealSubject implements Subject{ private String name = null; @Override public void doSomething() { System.out.println(this.name + "被代理,正在执行业务逻辑..."); } public RealSubject(Subject proxy,String name) throws Exception{ if(proxy == null){ throw new Exception("无法创建被代理对象"); }else{ this.name = name; } } } package GeneralProxy; public class Proxy implements Subject{ private Subject realsub = null; public Proxy(String name) { try { realsub = new RealSubject(this, name); } catch (Exception e) { e.printStackTrace(); } } public void doSomething() { realsub.doSomething(); } } package GeneralProxy; public class Client { public static void main(String[] args) { //普通代理 Subject proxy = new Proxy("张三"); proxy.doSomethaing(); } }強制代理: 必須透過存取特定主題類別來取得代理主題類別的對象,然後以代理主題類別控制存取
package MustProxy; public interface Subject { public void doSomething(); public Subject getProxy(); } package MustProxy; public class RealSubject implements Subject{ private String name = null; private Subject proxy = null; @Override public void doSomething() { if(isProxy()){ System.out.println(this.name + "被代理,正在执行业务逻辑..."); }else{ System.out.println("请先访问代理..."); } } public RealSubject(String name) { this.name = name; } public Subject getProxy() { proxy = new Proxy(this); return this.proxy; } private boolean isProxy(){ if(this.proxy == null){ return false; }else{ return true; } } } package MustProxy; public class Proxy implements Subject{ private Subject realSub = null; public Proxy(Subject realSub) { this.realSub = realSub; } public void doSomething() { this.realSub.doSomething(); } public Subject getProxy() { return this; } } package MustProxy; public class Client { public static void main(String[] args) { Subject realSub = new RealSubject("张三"); realSub.doSomething(); Subject proxy = realSub.getProxy(); proxy.doSomething(); } }
應用場景
現實世界中,秘書就相當於一個代理,老闆開會,那麼通知員工開會時間、佈置會場、會後整理會場等等開會相關工作就可以交給秘書做,老闆就只需要開會就行了,不需要親自做那些事。同理,在我們程式設計中也可使用代理模式來將由一系列無關邏輯組合在一起的程式碼進行解耦合,例如業務程式碼中的日誌程式碼就可以在代理程式中進行。 Spring的AOP就是典型的動態代理應用。代理模式的應用形式
(1)遠端代理(Remote 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),這不難理解。複雜隱藏代理和外觀模式是不一樣的,因為代理控制訪問,而外觀模式是不一樣的,因為代理控制訪問,而外觀模式只提供另一組介面。
更多實例講解Java設計模式程式設計如何運用代理模式相關文章請關注PHP中文網!