Proxy Pattern (代理模式)
The Proxy Pattern provides a surrogate or placeholder for another object to control access to it
- Design Patterns: Elements of Reusable Object
在 GoF 的書中
圖
using System;
namespace _
{
//用戶端程序
class Program
{
static void Main(string[] args)
{
//用戶把 Proxy (代理者) 視為 RealSubject (真實的對象) 來操作
Proxy proxy = new Proxy();
proxy
Console
}
}
//代理者
abstract class Subject
{
public abstract void Request();
}
//被代理者
class RealSubject : Subject
{
//真正做事的方法
public override void Request()
{
Console
}
}
//代理者
class Proxy : Subject
{
RealSubject realSubject;
public override void Request()
{
if (realSubject == null)
{
realSubject = new RealSubject();
}
realSubject
}
}
}
/*
執行結果
真實的請求
*/
上方圖
其中 RealSubject 是真正做事的對象
客戶端和 RealSubject 的互動
圖
Proxy Pattern 依照功能和目的
遠程代理 (Remote Proxy)
保護代理 (Protection Proxy; Access Proxy)
智能引用代理 (Smart Reference Proxy)
虛擬代理 (Virtual Proxy)
其他
在 GoF 中所舉的例子是 Virtual Proxy
圖
如上圖
using System;
using blogs
//客戶端程序
class Program
{
static void Main(string[] args)
{
//當文檔被打開時
IGraphic image
Console
Console
Console
image
Console
}
}
//服務器端程序
namespace blogs
{
//此為「代理者
public interface IGraphic
{
//用來畫圖的方法
void draw();
}
//被代理者
public class Image : IGraphic
{
private byte[] data;
public Image(String fileName) //構造函數
{
//載入圖片
//data = loadImage(fileName);
Console
}
public void draw()
{
//繪制圖片在屏幕上
//drawToScreen(data);
Console
}
}
//代理者
public class ImageProxy : IGraphic
{
private String fileName;
private Image image;
public ImageProxy(String filename) //構造函數
{
this
image = null;
}
//等到真正要顯示圖片了
//此時才會真正去創建 Image 對象
public void draw()
{
//虛擬代理
if (image == null)
{
image = new Image(fileName);
}
//實際去繪制圖片在螢幕上
image
}
}
} // end of namespace
/*
執行結果
文檔被開啟
用戶已把滾動條滾到特定頁數
開始載入圖片
圖片已成功繪制在屏幕上
*/
代理的主要目的之一
此外
接下來的第三個示例
這個 DbCommandProxy 類
圖
using System;
using blogs
using System
using System
using System
//客戶端程序
public partial class _Default : System
{
protected void Page_Load(object sender
{
IDbCommand command = new DbCommandProxy();
command
//顯示 Employees 表的記錄總數
this
}
}
//服務器端程序
namespace blogs
{
//這個類並非「被代理者」
//將具體建立數據庫連接…等
class DbContext
{
private string strProviderName;
private string strConnectionString;
public DbContext(string name) //構造函數
{
//取得 nfig 裡的數據庫連接字符串名稱
ConnectionStringSettings setting = ConfigurationManager
this
this
}
public DbConnection CreateConnection()
{
DbProviderFactory factory = DbProviderFactories
DbConnection connection = factory
connection
return connection;
}
}
//將「代理者
//此類同時為 RealSubject 和 Proxy 的類
public class DbCommandProxy : IDbCommand
{
private DbContext context;
private string strCommandText;
public DbCommandProxy(string name) //構造函數
{
if (string
ntext = new DbContext(name);
}
public DbCommandProxy() : this(
public object ExecuteScalar()
{
using (DbConnection connection = context
{
connection
DbCommand command = connection
command
command
return command
}
}
public string CommandText
{
get { return this
set { this
}
//IDbCommand 接口未被實現的成員
}
} // end of namespace
Proxy Pattern 適用的情景
對象創建的代價比較高
僅在操作被請求時創建對象
對象需要訪問控制
需要訪問遠程站點
被訪問時
Proxy Pattern 的優點
降低對象使用的復雜度
增加對象使用的友好度
提高程序的效率和性能 (如同 HTTP 的 Proxy Server)
Proxy Pattern 的缺點
和一些 Pattern 一樣
Proxy Pattern 的其他特性
Proxy Pattern 的結構
Decorator Pattern 替對象加上行為
Proxy Pattern 的關系是在設計階段就確定好了的
From:http://tw.wingwit.com/Article/program/net/201311/11289.html