[GoF] – Proxy Pattern

ถ้าหากจะพูดถึงเรื่อง Design Pattern  เราก็คงคิดถึง Gang of Four (GoF) ซึ่งถือว่าเป็น Classic Pattern โดยประกอบไปด้วย 23 Patterns แยกเป็น 3 หมวด คือ Creational Patterns, Structural Patterns, Behavioral Patterns วันนี้ผมขอหยิบบาง Pattern ในหมวด Structural Patterns มาพูด ซึ่งมันก็คือ Proxy Pattern มาดูกันครับ..

Proxy Pattern : Provide a surrogate or placeholder for another object to control access to it.

gof-proxy

สำหรับ Proxy Pattern ถ้ามองในมุมของโครงสร้างของ Class จะเห็นว่า Real Object กับ Proxy จะมี Interface เดียวกัน (มองง่ายๆ คือมี Method ชื่อเดียวกัน Return Type เดียวกัน) สิ่งสำคัญของ Proxy คือ Client จะมาเรียก Proxy Object แล้ว Proxy Object จะไปเรียก Real Object อีกทีนึงแบบนี้..

proxy object

ประโยชน์ที่ได้จากการใช้ Proxy Pattern คือ
Lazy-instantiate an object : ลองสังเกตุ Entity Framework (EF) ดูครับ Class ที่เป็น Domain Object เรามักจะกำหนด Property ให้มันเป็น Virtual (Object ลูกสามารถ Override Method แม่ได้) ซึ่งทำให้เราสามารถทำ Lazy Loading ได้ยกตัวอย่างเช่น ข้อมูล Master-Detail ในกรณีที่เรา Load Object Master ขึ้นมาข้อมูล Detail จะยังคงไม่โหลดมาจนกระทั่งเราเรียกใช้ ซึ่งจะช่วยในเรื่อง Performance นั่นเองครับ
Control access to the object : เนื่องจากเราเรียก Proxy Class ก่อนที่ Real Object จะถูกเรียกจริง นั่นคือ เราสามารถ Check สิทธิ์การเข้าใช้ก่อนจะเรียก Real Object ได้นั่นเอง
Hide the fact object : บางครั้งเราต้องไปเรียกข้อมูลจากระบบอื่นมาใช้ ซึ่งระหว่างการ Develop เราก็สามารถสร้าง Proxy Class มาบังเพื่อ Return ค่าที่เราต้องการ ออกไปให้ Client ก่อน โดยที่เรายังไม่ต้องไปเรียก Service จริงๆนั่นเอง

   public abstact class CustomerBase
   {
         public abstact string GetName();
   }

   public class Customer : CustomerBase
   {
       public override string GetName()
       {
           return "Customer Name";
       }
   }

   public class CustomerProxy : CustomerBase
   {
      //Instantiation Real Object
       private readonly Customer _realCustomer = new Customer();

       public override string GetName()
       {
           //Logging, Control Access ...

           return "Proxy of " + _realCustomer.GetName();
       }
   }

   //Client Call
   //เราสามารถใช้ Factory ในการสร้าง Object ได้โดยขึ้นอยู่กับว่าเราจะให้ Return Real Object หรือ Proxy Object
   var customerFactory = new CustomerFactory();
   var customer = customerFactory.GetCustomer();
   var name = customer.GetName();

*** สรุป ***
– Proxy Class กับ Real Class จะมี Interface(ในที่นี้ คือ Abstract Class ชื่อ CustomerBase) เดียวกันกับ Real Object
– ในการ Implement Proxy Class คือ จะทำการ Instantiation Real Object ภายในนั้นเลย
– Proxy Class มันก็คือ Wrapping Class ชนิดหนึ่งนั่นแหละครับ
– ปกติผมไม่ได้สร้าง Proxy Class ขึ้นมาใช้เองแต่มักจะใช้งานผ่าน Framework ต่างๆมากกว่า เช่น
EF เพื่อทำ Lazy Loading แบบที่บอกไปก่อนหน้านี้ หรือใช้ Castle.Core ที่เป็น Dynamic Proxy ใช้คู่กับ StructureMap เพื่อทำ AOP เป็นต้น ซึ่งหากใครต้องการข้อมูลเพิ่มเติมสามารถดูได้ ที่นี่ Happy coding ครับ

tapez@555
You must unlearn what you have learned.

Leave a comment