代理模式的目地是為對象提供一種代理以控制對這個對象的訪問。為什麼會出現“通過一個代理對象,控制其他對象訪問目標對象”這種場景,而不知直接new()出一個對象直接使用呢?這是因為在有些場景下對象的訪問比較複雜,且需要一些額外的控制,這時如果直接new()出實例,併在調用端處理這些繁雜的細節,會增加系統 ...
代理模式的目地是為對象提供一種代理以控制對這個對象的訪問。為什麼會出現“通過一個代理對象,控制其他對象訪問目標對象”這種場景,而不知直接new()出一個對象直接使用呢?這是因為在有些場景下對象的訪問比較複雜,且需要一些額外的控制,這時如果直接new()出實例,併在調用端處理這些繁雜的細節,會增加系統的耦合。類似的場景有很多,比如遠程訪問、資料庫訪問、許可權校驗、負載均衡等等。
GOF對外觀模式的描述為:
Provide a surrogate or placeholder for another object to control accessto it...
— Design Patterns : Elements of Reusable Object-Oriented Software
UML類圖:
代理類本身也實現了ISubject介面,但在具體調用時,它會把請求轉向一個RealSubject對象進行真正的處理。
代碼實現:
public interface ISubject
{
string Request();
}
public class RealSubject : ISubject
{
public string Request()
{
return "From real subject";
}
//這裡使用Singleton的目地是模擬複雜性,比如客戶程式並不知道如何使用遠端的具體類型
private static ISubject singleton = new RealSubject();
private RealSubject() { }
public static ISubject GetInstance()
{
return singleton;
}
}
public class Proxy : ISubject
{
public string Request()
{
//預處理
var result= RealSubject.GetInstance().Request();
//後處理
return result;
}
}
在代碼示例中,使用Singleton模擬對象訪問的複雜性,然後使用代理封裝了這種複雜性,同時對訪問的控制可以在預處理、後處理的部分擴展。
使用代理對象需要註意的幾個問題
- 引入代理對象並不應該增加客戶程式的複雜性,按照依賴倒置的原則,客戶程式需要知道的也只是目標對象的抽象介面,因此相應的代理對象也就應該實現這個介面,否則等於變相向客戶程式引入新的複雜性。
- 代理的目的是控制客戶程式對目標對象的訪問,因此代理必須可以直接或間接地知道目標類型在哪,以及如何訪問。
- 代理類不必知道具體的目標類型,很多時候它只要能夠按照與客戶程式統一的約定,提供一個具有抽象特征的類型即可,代理類也只依賴抽象類型,至於具體目標類型,可以組合使用創建型模式來實現。
代理模式的優點
- 職責清晰,具體目標類型只需要實現實際的業務邏輯,而不用關心其他非本職責的事務,通過後期的代理完成這些事務,附帶的結果就是編程簡潔清晰。
- 代理對象可以在客戶端和目標對象之間起到中介的作用,起到保護目標對象的作用。
- 高擴展性。
代理模式的缺點
- 代理模式會造成系統設計中類的數目的增加。
- 由於在客戶端和真實主題之間增加了代理對象,因此有些類型的代理模式可能會造成請求的處理速度變慢。
- 增加了系統的複雜度。
參考書籍:
王翔著 《設計模式——基於C#的工程化實現及擴展》