
الگوی طراحـــــــــی Proxy
الگوی طراحی Proxy یکی از الگوهای ساختاری (Structural Patterns) است که هدف آن ایجاد یک نماینده (Proxy) برای کنترل دسترسی به یک شیء و یا سرویس است. این الگو به ما امکان ایجاد یک لایه میانی اضافی (Proxy) را میدهد که به عنوان یک واسط بین کاربر و شیء اصلی عمل میکند و میتواند کارهایی مانند اعتبارسنجی، حمایت از دسترسی و یا کاهش بار را بر عهده بگیرد.
برای مثال واقعی فرض کنید شما یک برنامه مدیریت ویدئوها دارید و میخواهید از یک وب سرویس برای دریافت ویدئوها استفاده کنید. اما از آنجایی که ارتباط با وب سرویس ممکن است زمانبر و هزینهبر باشد، میخواهید از Proxy برای ذخیرهسازی ویدئوها در حافظهای موقت استفاده کنید تا از دسترسیهای مکرر به وب سرویس جلوگیری کنید و همچنین دسترسی را بهبود دهید.
حالا بیایید با استفاده از زبان سیشارپ یک مثال از الگوی Proxy با ساخت یک کلاس سادهای به نام "VPN" انجام دهیم:
1using System;
2
3// کلاس اصلی (Subject)
4public interface IInternet
5{
6 void ConnectTo(string serverHost);
7}
8
9// پیادهسازی کلاس اصلی (RealSubject)
10public class RealInternet : IInternet
11{
12 public void ConnectTo(string serverHost)
13 {
14 Console.WriteLine($"Connecting to {serverHost} directly...");
15 }
16}
17
18// کلاس Proxy
19public class InternetProxy : IInternet
20{
21 private IInternet realInternet;
22 private string vpnServerHost;
23
24 public InternetProxy()
25 {
26 // در اینجا یک شئ از کلاس واقعی ایجاد میشود
27 realInternet = new RealInternet();
28 vpnServerHost = "vpn.server.com";
29 }
30
31 public void ConnectTo(string serverHost)
32 {
33 if (serverHost.Contains(vpnServerHost))
34 {
35 Console.WriteLine("You are not allowed to access VPN server directly.");
36 return;
37 }
38
39 realInternet.ConnectTo(serverHost);
40 }
41}
42
43public class Program
44{
45 public static void Main()
46 {
47 IInternet internet = new InternetProxy();
48
49 // تلاش برای دسترسی مستقیم به VPN
50 internet.ConnectTo("vpn.server.com");
51
52 // تلاش برای دسترسی به یک وبسایت دیگر
53 internet.ConnectTo("example.com");
54 }
55}
خروجی برنامه به صورت زیر خواهد بود:
You are not allowed to access VPN server directly.
Connecting to example.com directly...
در این مثال با استفاده از الگوی Proxy، توانستیم یک Proxy به عنوان واسط برای دسترسی به VPN ساخته و قابلیت اعتبارسنجی را به آن اضافه کنیم. این الگو به ما امکان محدود کردن دسترسی به منابع و کنترل بار را میدهد و برنامهنویسی را سادهتر میکند.
یک مثال دیگر:
الگوی Proxy در بسیاری از موارد کاربرد دارد، از جمله کنترل دسترسی، نگهداری نسخههای کش شده از دادهها، بارگذاری تنبلی (Lazy Loading) و غیره. یکی از کاربردهای متفاوت و کاربردیتر الگوی Proxy، استفاده از آن برای بهینهسازی عملیات بر روی تصاویر بزرگ است.
فرض کنید یک برنامه دارید که تصاویر بزرگی را از اینترنت بارگیری میکند و به کاربران نمایش میدهد. با توجه به حجم بزرگ تصاویر، بارگذاری و نمایش آنها ممکن است مدت زمان زیادی طول بکشد و حتی باعث کندی برنامه شود. به علاوه، احتمال وقوع خطا در این فرآیند بیشتر است. در این حالت، میتوانیم از الگوی Proxy استفاده کنیم تا تصاویر بزرگ را تنها در صورت نیاز بارگذاری کنیم و بهبود عملکرد برنامه را ایجاد کنیم.
بیایید با استفاده از زبان سیشارپ، این الگو را برای بارگذاری تنبلی (Lazy Loading) تصاویر بزرگ اجرا کنیم:
1using System;
2
3// کلاس اصلی (Subject)
4public interface IImage
5{
6 void Display();
7}
8
9// پیادهسازی کلاس اصلی (RealSubject)
10public class RealImage : IImage
11{
12 private string fileName;
13
14 public RealImage(string fileName)
15 {
16 this.fileName = fileName;
17 LoadFromDisk();
18 }
19
20 public void Display()
21 {
22 Console.WriteLine($"Displaying {fileName}");
23 }
24
25 private void LoadFromDisk()
26 {
27 // بارگذاری تصویر از دیسک (عملیات زمانبر)
28 Console.WriteLine($"Loading {fileName} from disk...");
29 }
30}
31
32// کلاس Proxy
33public class ImageProxy : IImage
34{
35 private RealImage realImage;
36 private string fileName;
37
38 public ImageProxy(string fileName)
39 {
40 this.fileName = fileName;
41 }
42
43 public void Display()
44 {
45 if (realImage == null)
46 {
47 // بارگذاری تنبلی تصویر از دیسک (فقط انجام میشود در صورت نیاز)
48 realImage = new RealImage(fileName);
49 }
50
51 realImage.Display();
52 }
53}
54
55public class Program
56{
57 public static void Main()
58 {
59 // ایجاد یک Proxy برای تصویر بزرگ
60 IImage image = new ImageProxy("large_image.jpg");
61
62 // تصویر بزرگ بارگذاری نمیشود تا زمانی که از آن نیاز باشد
63 image.Display();
64
65 // تصویر بزرگ این بار نیز بارگذاری نمیشود چون قبلاً بارگذاری شده است
66 image.Display();
67 }
68}
خروجی برنامه به صورت زیر خواهد بود:
Loading large_image.jpg from disk...
Displaying large_image.jpg
Displaying large_image.jpg
در این مثال با استفاده از الگوی Proxy و اصول بارگذاری تنبلی، توانستیم تصویر بزرگ را تنها در صورت نیاز بارگذاری کنیم و از این طریق بهبود عملکرد برنامه را بهبود ببخشیم. همچنین، بارگذاری تصویر از دیسک به صورت تنبلی (Lazy Loading) انجام میشود که میتواند زمان اجرای برنامه را کاهش دهد و مصرف حافظه را بهینه کند.