Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C#

Proxy Design Pattern คืออะไร และการนำไปใช้ใน C#

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