代理模式為某對象提供一個代理,由代理控制對原對象的引用。代理在客戶端與目標對象間起中介作用,適用於客戶端不想或不能直接引用目標對象的場景。
| 類型 | 用途 |
|---|---|
| 遠程代理 | 為不同地址空間的對象提供本地代表(如 Web Service、.NET Remoting) |
| 虛擬代理 | 按需創建資源消耗大的對象(如大圖片延遲加載) |
| Copy-on-Write 代理 | 延遲複製操作至真正需要時 |
| 保護代理 | 控制訪問權限,不同用戶不同權限 |
| Cache 代理 | 暫存操作結果供多客戶端共享 |
| 防火牆代理 | 保護目標免受惡意訪問 |
| 同步化代理 | 多用戶並發訪問同一對象無衝突 |
| 智能引用代理 | 引用時執行額外操作(如計數、鎖定) |
最常見的是:虛擬、遠程、智能引用、保護代理。
《西遊記》中悟空變作高翠蘭模樣會見豬八戒,完美詮釋保護代理:



三大角色:抽象主題、代理主題(持有真實主題引用、控制訪問、可在前後執行額外邏輯)、真實主題。
// Proxy pattern -- Structural example
using System;
abstract class Subject { abstract public void Request(); }
class RealSubject : Subject {
override public void Request() { Console.WriteLine("Called RealSubject.Request()"); }
}
class Proxy : Subject {
RealSubject realSubject;
override public void Request() {
if (realSubject == null) realSubject = new RealSubject(); // 惰性初始化
preRequest();
realSubject.Request();
postRequest();
}
public void preRequest() { Console.WriteLine("PreRequest."); }
public void postRequest() { Console.WriteLine("PostRequest."); }
}
public class Client {
public static void Main() {
Proxy p = new Proxy(); p.Request();
}
}
// Proxy pattern -- Real World example
using System; using System.Runtime.Remoting;
public interface IMath {
double Add(double x, double y);
double Sub(double x, double y);
double Mul(double x, double y);
double Div(double x, double y);
}
class Math : MarshalByRefObject, IMath {
public double Add(double x, double y) { return x + y; }
public double Sub(double x, double y) { return x - y; }
public double Mul(double x, double y) { return x * y; }
public double Div(double x, double y) { return x / y; }
}
class MathProxy : IMath {
Math math;
public MathProxy() {
AppDomain ad = AppDomain.CreateDomain("MathDomain", null, null);
ObjectHandle o = ad.CreateInstance("Proxy_RealWorld", "Math", false,
System.Reflection.BindingFlags.CreateInstance, null, null, null, null, null);
math = (Math)o.Unwrap();
}
public double Add(double x, double y) { return math.Add(x, y); }
public double Sub(double x, double y) { return math.Sub(x, y); }
public double Mul(double x, double y) { return math.Mul(x, y); }
public double Div(double x, double y) { return math.Div(x, y); }
}
public class ProxyApp {
public static void Main() {
MathProxy p = new MathProxy();
Console.WriteLine("4 + 2 = {0}", p.Add(4, 2));
Console.WriteLine("4 - 2 = {0}", p.Sub(4, 2));
Console.WriteLine("4 * 2 = {0}", p.Mul(4, 2));
Console.WriteLine("4 / 2 = {0}", p.Div(4, 2));
}
}
代理在構造函數中於獨立 AppDomain 創建真實對象,客戶端透明調用,實現隔離與安全。