1. 程式人生 > >代理模式(Proxy Pattern)(一):代理模式介紹

代理模式(Proxy Pattern)(一):代理模式介紹

一、意圖

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

二、適用性

使用代理模式的常見的重要情況有:

1) 遠端(Remote)代理:為一個位於不同的地址空間的物件提供一個局域代表物件。比如:你可以將一個在世界某個角落一臺機器通過代理假象成你區域網中的一部分。

2) 虛擬(Virtual)代理:根據需要將一個資源消耗很大或者比較複雜的物件延遲的真正需要時才建立。比如:如果一個很大的圖片,需要花費很長時間才能顯示出來,那麼當這個圖片包含在文件中時,使用編輯器或瀏覽器開啟這個文件,這個大圖片可能就影響了文件的閱讀,這時需要做個圖片Proxy 來代替真正的圖片。

3) 保護(Protect or Access)代理:控制對一個物件的訪問許可權。比如:在論壇中,不同的身份登陸,擁有的許可權是不同的,使用代理模式可以控制權限。

4) 智慧引用(Smart Reference)代理:提供比對目標物件額外的服務。比如:紀錄訪問的流量,提供一些友情提示等等。

還有其他情況也較為常見:

1)寫時複製(Copy-on-Write)代理:虛擬代理的一種。把複製(克隆)拖延到只有在客戶端需要時,才真正採取行動。

2)快取(Cache)代理:為某一個目標操作的結果提供臨時的儲存空間,以便多個客戶端可以共享這些結果。

3)防火牆(Firewall)代理:保護目標,不讓惡意使用者接近。

4)同步(Synchronization)代理:使幾個使用者能夠同時使用一個物件而沒有衝突。

三、組成

——抽象角色(Subject):宣告真實物件和代理物件的共同介面,這樣,在任何使用真實物件的地方都可以使用代理物件。

——代理角色(Proxy):代理物件角色內部含有對真實物件的引用,從而可以操作真實物件,同時代理物件提供與真實物件相同的介面以便在任何時刻都能代替真實物件。同時代理物件可以在執行真實物件操作時,附加其他的操作,控制對真實物件的訪問。

——真實角色(RealSubject):代理角所代表的真實物件,是我們最終要引用的物件。

四、結構

五、簡單實現

1.抽象角色(Subject)

public interface Subject
{
	public void request();
}


2.真實角色(RealSubject)

public class RealSubject implements Subject
{
	@Override
	public void request()
	{
		System.out.println("from real subject");
	}

}

3.代理角色(Proxy)

public class Proxy implements Subject
{
	Subject realSubject;

	@Override
	public void request()
	{
		this.preRequest();// 控制訪問
		if (this.realSubject == null)
			this.realSubject = new RealSubject();
		this.realSubject.request();
		this.afterRequest();
	}

	// 加入新的操作
	public void preRequest()
	{
		System.out.println("pre request");
	}

	public void afterRequest()
	{
		System.out.println("after request");
	}
}

4.測試

public class Client
{
	public static void main(String[] args)
	{
		Subject subject = new Proxy();
		subject.request();
	}
}

六、其他

1.使用代理模式建立代理物件,讓代理物件控制對真實物件的訪問,被代理的物件可以是遠端物件、建立開銷大的物件或需要安全控制的物件。遠端代理管理客戶和遠端物件之間的互動,虛擬代理控制訪問例項化開銷大的物件,保護代理基於呼叫者控制物件方法的訪問。

2.與其他模式比較:裝飾者 模式為物件加上新的行為或責任,而代理模式則是控制訪問,並不提供物件本身的增強功能;介面卡模式是改變所考慮的物件的介面,而代理模式並不能改變所代理的物件的介面;

3.遠端代理(Remote Proxy)不包含對實體的直接引用,而只是一個間接引用,如“主機I D,主機上的區域性地址”。虛擬代理(Virtual Proxy)開始的時候使用一個間接引用,例如一個檔名,但最終將獲取並使用一個直接引用。

3.如果按照上述方法使用代理模式,那麼真實角色必須是事先存在的,並且將其作為代理物件的內部屬性。但是,實際使用時,一個真實角色必須對應一個代理角色,如果大量使用會導致類的急劇膨脹(就像裝飾者模式的弊端一樣),此外,如果事先不知道真實角色呢,將如何代理?這些問題可以通過java的動態代理類來解決(相對於java的動態代理,上面的代理方式可稱為靜態代理)。

轉載請註明出處:http://blog.csdn.net/jialinqiang/article/details/8949147