Design Pattern — 代理模式(Proxy Pattern)

莊創偉
Feb 1, 2021

--

維基說明

說明:不直接訪問目標而是透過代理對象來訪問目標。優點:透過代理對象執行目標,可以在不改變目標行為的狀況下添加一些的額外處理缺點:多透過一層代理對象,多少會降低效能

假設我們有個簡單的方法

class RealItem{
public void DoSomething(){
Console.WriteLine("DoSomething");
}
}

如果要測量這個方法執行需要花多少時間的話,很容易寫成這樣

Stopwatch watch = new Stopwatch();watch.Start();new RealItem().DoSomething();watch.Stop();Console.WriteLine("花費時間 :" + watch.ElapsedMilliseconds + "毫秒");

而假使我們希望每次執行都記錄花費時間,可以將上述語法包起來成為一個方法放進一個代理類別裡,再去執行。

這種在程式編譯期間定義好代理類別,讓代理物件具有實體的方法稱為靜態代理

靜態代理有兩個主要的缺點,一是多了很多的程式碼,二是擴充不易。

如上為了代理原本的方法需要額外添加一個介面與代理類別。當需要代理的類別與方法一多就會造成維護上的困難。

靜態代理自然就有與之相對的動態代理。

動態代理是在程式運行期間捕抓需代理的行為動態添加程式。C#可以透過System.Reflection.Emit 動態添加 IL 來實現。但必須學習 IL 相關知識較為困難。

另外動態代理相對於靜態代理效能較為低落,畢竟需要動態生成程式。但好處是可以擺脫代理類侵入且泛用性較高

代理類侵入

在上面的程式中,為了實現代理行為,所以須操作PorxyItem這個代理物件而非RealItem ,這種狀況稱之為代理類侵入

假使原生類別擁有許多方法,這些方法需要透過不同的代理物件執行時,會讓程式變得相當複雜且不直觀。

--

--

莊創偉

學海無涯。但是為了生計還是得下海的風塵男子