Proxy Pattern เป็น Structural Design Pattern ที่ให้ออบเจกต์ตัวแทน (Surrogate/Placeholder) ควบคุมการเข้าถึงออบเจกต์จริง (Real Subject) โดย Proxy และ Real Subject ต้อง Implement Interface เดียวกัน เพื่อให้สามารถแทนที่กันได้
ผู้เข้าร่วม (Participants)
- Subject (Interface): กำหนด Interface ร่วมสำหรับ RealSubject และ Proxy
- RealSubject: ออบเจกต์จริงที่ Proxy แทน
- Proxy: เก็บ Reference ไปยัง RealSubject ควบคุมการเข้าถึง Implement Interface เดียวกัน
กรณีใช้งานทั่วไป
- Virtual Proxy: สร้าง Object ให้น่าหนัก (Heavy) เมื่อจำเป็นจริง (Lazy Loading)
- Protection Proxy: ควบคุมสิทธิ์การเข้าถึง (Access Control)
- Remote Proxy: แทน Object ที่อยู่บนเครื่องอื่น (RPC, Web Service)
- Logging/Caching Proxy: เพิ่ม Logging หรือ Caching ก่อนส่งต่อไป RealSubject
ตัวอย่างโค้ด: Virtual Proxy สำหรับ Image Loading
// Subject Interface
public interface IImage
{
void Display();
}
// Real Subject - โหลดรูปจริง (Heavy)
public class RealImage : IImage
{
private readonly string _filename;
public RealImage(string filename)
{
_filename = filename;
LoadFromDisk(); // จำลองโหลดจาก Disk
}
private void LoadFromDisk()
{
Console.WriteLine($"Loading {_filename} from disk...");
Thread.Sleep(1000); // Simulate delay
}
public void Display() => Console.WriteLine($"Displaying {_filename}");
}
// Proxy - โหลด Lazy
public class ProxyImage : IImage
{
private readonly string _filename;
private RealImage _realImage;
public ProxyImage(string filename) => _filename = filename;
public void Display()
{
// สร้าง RealImage ครั้งแรกที่ต้องใช้ (Lazy Initialization)
_realImage ??= new RealImage(_filename);
_realImage.Display();
}
}
// Client
static void Main()
{
IImage image = new ProxyImage("photo.jpg");
Console.WriteLine("Image object created, but not loaded yet.");
image.Display(); // โหลดและแสดงครั้งแรก
image.Display(); // แสดงทันที (Cached)
}
ผลลัพธ์
Image object created, but not loaded yet.
Loading photo.jpg from disk...
Displaying photo.jpg
Displaying photo.jpg
ข้อดี
- ควบคุมการเข้าถึงได้ (Security, Lazy Loading, Caching, Logging)
- Client ไม่ต้องรู้ว่ากำลังใช้ Proxy หรือ Real Object
- ปฏิบัติตาม Open/Closed Principle
ใน .NET Framework
System.Runtime.Remoting.Proxies.RealProxy(Legacy Remoting)DynamicProxy(Castle DynamicProxy) - ใช้สร้าง Proxy Runtime สำหรับ AOP (Logging, Transaction, Validation)- Entity Framework ใช้ Proxy สำหรับ Lazy Loading Navigation Properties