1. 程式人生 > >[設計模式-結構型]代理模式(Proxy)

[設計模式-結構型]代理模式(Proxy)

概括

名稱

Proxy

結構

動機

為其他物件提供一種代理以控制對這個物件的訪問。

適用性

  • 在需要用比較通用和複雜的物件指標代替簡單的指標的時候,使用P r o x y 模式。下面是一 些可以使用P r o x y 模式常見情況:

  • 1) 遠端代理(Remote Proxy )為一個物件在不同的地址空間提供區域性代表。 NEXTSTEP[Add94] 使用N X P r o x y 類實現了這一目的。Coplien[Cop92] 稱這種代理為?大使? (A m b a s s a d o r )。

  • 2 )虛代理(Virtual Proxy )根據需要建立開銷很大的物件。在動機一節描述的I m a g e P r o x y 就是這樣一種代理的例子。

  • 3) 保護代理(Protection Proxy )控制對原始物件的訪問。保護代理用於物件應該有不同 的訪問許可權的時候。例如,在C h o i c e s 作業系統[ C I R M 9 3 ]中K e m e l P r o x i e s 為作業系統物件提供 了訪問保護。

  • 4 )智慧指引(Smart Reference )取代了簡單的指標,它在訪問物件時執行一些附加操作。 它的典型用途包括:

  • 對指向實際物件的引用計數,這樣當該物件沒有引用時,可以自動釋放它(也稱為S m a r tP o i n t e r s[ E d e 9 2 ] )。

  • 當第一次引用一個持久物件時,將它裝入記憶體。

  • 在訪問一個實際物件前,檢查是否已經鎖定了它,以確保其他物件不能改變它。


解析

形象比喻:

  跟MM在網上聊天, 一開頭總是,“hi, 你好”,“你從哪兒來呀?”,“你多大了?”,“身高多少呀?” 這些話,真煩人, 寫個程式做為我的Proxy 吧, 凡事接收到這些話都設定好自動的回答,接收到其他的話時再通知我回答,怎麼樣。

  代理模式中的“代理商”要想實現代理任務, 就必須和被代理的“廠商”使用共同的介面。於是代理模式就有三個角色組成了:

1) 抽象主題角色: 聲明瞭真實主題和代理主題的共同介面

2) 代理主題角色: 內部包含了對真實主題的應用, 並且提供和真實主題角色相同的介面

3) 真實主題物件: 定義真實的物件

代理模式能夠協調呼叫者和被呼叫者, 能夠在一定程度上降低系統的耦合度。代理模式中真實主題角色可以結合組合模式來構造,這要一個代理主題角色就可以對一系列這是主題角色有效,提高程式碼的利用率,較少不必要子類的產生。

例項

涉及的檔案:

抽象角色 Subject.java

真實角色 -RealSubject.java

代理角色 - ProxySubject.java

測試類: TestMain.java

/**   
 * @author oscar999   
 * @date 2014-4-28
 * @version V1.0   
 */
package designptn.proxy;

public abstract class Subject {
	abstract public void request();
}

/**   
 * @author oscar999   
 * @date 2014-4-28
 * @version V1.0   
 */
package designptn.proxy;

public class RealSubject extends Subject {

	public RealSubject(){
		
	}

	@Override
	public void request() {
		System.out.println("From real subject.");
	}

}

/**   
 * @author oscar999   
 * @date 2014-4-28
 * @version V1.0   
 */
package designptn.proxy;

public class ProxySubject extends Subject {

	private RealSubject realSubject;

	public ProxySubject() {
	}

	@Override
	public void request() {
		// preRequest();
		if (realSubject == null) {
			realSubject = new RealSubject();
		}
		realSubject.request();
		// postRequest();
	}

}

/**   
 * @author oscar999   
 * @date 2014-4-28
 * @version V1.0   
 */
package designptn.proxy;

public class TestMain {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Subject sub = new ProxySubject();
        sub.request();
    }

}

遠端代理可以將網路的細節隱藏起來,使得客戶端不必考慮網路的存在
對於一些佔用系統資源較多或者載入時間較長的物件,可以給這些物件提供一個虛擬代理
緩衝代理(Cache Proxy)也是一種較為常用的代理模式,它為某一個操作的結果提供臨時的快取儲存空間,以便在後續使用中能夠共享這些結果,從而可以避免某些方法的重複執行,優化系統性能