意圖
為其他對象提供一種代理以控制對這個對象的訪問。
場景
代理模式非常常用,大致的思想就是通過為對象加一個代理來降低對象的使用復雜度、或是提升對象使用的友好度、或是提高對象使用的效率。在現實生活中也有很多代理的角色,比如明星的經紀人,他就是一種代理,經紀人為明星處理很多對外的事情,目的是為了節省被代理對象也就是明星的時間。保險代理人幫助投保人辦理保險,目的降低投保的復雜度。
在開發中代理模式也因為目的不同效果各不相同。比如,如果我們的網站程序是通過.NET Remoting來訪問帳號服務的。在編寫代碼的時候可能希望直接引用帳號服務的DLl ,直接實例化帳號服務的類型以方便調試。那麼,我們可以引入Proxy模式,做一個帳號服務的代理,網站只需要直接調用代理即可。在代理內部實現正式和測試環境的切換,以及封裝調用.NET Remoting的工作。
示例代碼
using System;
using System.Collections.Generic;
using System.Text;
namespace ProxyExample
{
class Program
{
static void Main(string[] args)
{
AccountProxy ap = new AccountProxy();
ap.Register();
}
}
interface IAccount
{
void Register();
}
class Account : IAccount
{
public void Register()
{
System.Threading.Thread.Sleep(1000);
Console.WriteLine("Done");
}
}
class AccountProxy : IAccount
{
readonly bool isDebug = true;
IAccount account;
public AccountProxy()
{
if (isDebug)
account = new Account();
else
account = (IAccount)Activator.GetObject(typeof(IAccount), "uri");
}
public void Register()
{
Console.WriteLine("Please wait...");
account.Register();
}
}
}
代碼說明
l IAccount就是抽象主題角色。代理對象和被代理對象都遵循這個接口,這樣代理對象就能替換被代理對象。
l AccountProxy就是代理主題角色。代理主題通常會存在一些邏輯或預處理或後處理操作,不會僅僅是對操作的轉發。
l Account就是真實主題角色。
何時采用
l 代理模式應用非常廣泛,如果你希望降低對象的使用復雜度、或是提升對象使用的友好度、或是提高對象使用的效率都可以考慮代理模式。
實現要點
l 代理對象和被代理對象都遵循一致的接口。
l 在某些情況下,可以不必保持接口一致性,如果封裝確實需要損失一些透明度,那麼也可以認為是Proxy。
注意事項
l Proxy、Facade以及Adapter可能都是對對象的一層封裝,側重點不同。Proxy基於一致的接口進行封裝,Facade針對封裝子系統,轉化為高層接口,而Adapter的封裝是處於適配接口的目的。