1. چیست الگوی نمونهای (Proxy Pattern)
الگوی نمونهای (Proxy Pattern) یک الگوی طراحی ساختاری است که به عنوان یک نماینده (proxy) عمل میکند تا دسترسی به یک شیء خاص را کنترل کند. بر اساس شیء هدف (شیءی که توسط proxy نماینده میشود)، الگوی نمونهای یک شیء proxy ارائه میدهد که کلاینتها میتوانند از طریق آن به شیء هدف دسترسی پیدا کنند و این امکان را فراهم میکند که قابلیتهای اضافی به شیء هدف اضافه شوند.
1.1 تعریف الگوی نمونهای (Proxy Pattern)
الگوی نمونهای (Proxy Pattern) یک الگوی طراحی است که شامل همکاری دو یا چند شیء است. یکی از این اشیاء شیء هدف واقعی است که فراخوانی میشود، در حالی که یک یا چند شیء دیگر به عنوان اشیاء proxy عمل میکنند. اشیاء proxy دسترسی به شیء هدف را از میان میگیرند و یک راه غیرمستقیم برای دسترسی به شیء هدف فراهم میکنند.
1.2 هدف و اهداف الگوی نمونهای (Proxy Pattern)
هدف اصلی الگوی نمونهای (Proxy Pattern) ایجاد یک راه غیرمستقیم برای دسترسی به شیء هدف است، که اجازه میدهد قابلیتهای اضافی به شیء هدف اضافه شود. اشیاء proxy میتوانند منطقهای مشترکی را انجام دهند، مانند کنترل دسترسی به شیء هدف، حافظه پنهان (caching) و ثبت رویدادها (logging). الگوی نمونهای (Proxy Pattern) همچنین میتواند بارگذاری تنبل (lazy loading) را پیادهسازی کند، بهطوریکه شیء هدف فقط در صورت نیاز نمونهسازی شود.
2. ویژگیها و مزایای الگوی نمونهای (Proxy Pattern)
الگوی نمونهای (Proxy Pattern) دارای ویژگیها و مزایای زیر است:
- قابلیت گسترش قابلیتهای شیء هدف بدون تغییر آن.
- کنترل دسترسی به شیء هدف از طریق شیء proxy.
- انجام عملیات اضافی قبل یا بعد از دسترسی به شیء هدف.
- امکان پیادهسازی بارگذاری تنبل، فقط موقع نیاز شیء هدف را نمونهسازی کند.
3. نمونههای کاربردی عملی الگوی نمونهای (Proxy Pattern)
الگوی نمونهای (Proxy Pattern) در بسیاری از سناریوهای کاربردی استفاده میشود. در زیر چند نمونه معمول از کاربردهای عملی آورده شده است:
- Proxy از راه دور: برای دسترسی به اشیاء در شبکه به صورت محلی استفاده میشود.
- Proxy مجازی: برای ایجاد اشیاء گرانقیمت در هنگام نیاز استفاده میشود.
- Proxy امنیتی: برای کنترل دسترسی به اشیاء استفاده میشود.
- ارجاع هوشمند: برای انجام عملیات اضافی هنگام دسترسی به اشیاء مانند شمارش اشیاء استفاده میشود.
4.1 نمودار کلاس UML
در زیر نمودار کلاس UML الگوی نمونهای (Proxy Pattern) در Golang آمده است:
4.2 مقدمه مثال
فرض کنید یک رابط Subject
داریم که یک متد Request
را تعریف میکند. کلاس پیادهسازی واقعی RealSubject
را داریم که رابط Subject
را پیادهسازی میکند. سپس یک کلاس نماینده Proxy
ایجاد میشود که یک شیء RealSubject
را نگهداری میکند و همچنین رابط Subject
را پیادهسازی میکند. در متد Request
کلاس Proxy
، میتوانیم عملیات اضافی قبل یا بعد از فراخوانی متد Request
از RealSubject
انجام دهیم.
4.3 گام ۱: تعریف رابط Proxy
در ابتدا، نیاز داریم یک رابط Subject
را تعریف کنیم که حاوی یک متد Request
باشد:
package main
type Subject interface {
Request()
}
4.4 گام ۲: پیادهسازی شیء هدف
سپس، شیء هدف خاص RealSubject
را پیادهسازی میکنیم که رابط Subject
را پیادهسازی میکند:
package main
import "fmt"
type RealSubject struct {}
func (r *RealSubject) Request() {
fmt.Println("RealSubject: Handling Request")
}
4.5 گام ۳: پیادهسازی شیء نماینده
سپس، یک شیء نماینده Proxy
ایجاد میکنیم که یک شیء RealSubject
را نگهداری میکند و رابط Subject
را پیادهسازی میکند. در متد Request
کلاس Proxy
، میتوانیم قبل یا بعد از فراخوانی متد Request
شیء RealSubject
، عملیات اضافی انجام دهیم:
package main
import "fmt"
type Proxy struct {
realSubject *RealSubject
}
func (p *Proxy) Request() {
fmt.Println("Proxy: Pre-Request")
if p.realSubject == nil {
p.realSubject = &RealSubject{}
}
p.realSubject.Request()
fmt.Println("Proxy: Post-Request")
}
4.6 گام ۴: فراخوانی شیء نماینده
در نهایت، میتوانیم از شیء نماینده Proxy
استفاده کنیم تا متدهای شیء از RealSubject
را فراخوانی کنیم:
package main
func main() {
proxy := Proxy{}
proxy.Request()
}
اجرای کد فوق خروجی زیر را تولید میکند:
Proxy: Pre-Request
RealSubject: Handling Request
Proxy: Post-Request
5.1 تفاوت و ارتباط بین الگوی پروکسی و الگوی دکوراتور
هر دو الگوی پروکسی و الگوی دکوراتور الگوهای طراحی ساختاری هستند که شامل یک شی هدف و یک شی پروکسی/دکوراتور میباشند. با این حال، تفاوتهایی بین این دو وجود دارد:
- الگوی پروکسی به طور کلی شامل کنترل دسترسی به شی هدف است، در حالی که الگوی دکوراتور بیشتر بر توسعه شی هدف تمرکز دارد.
- الگوی پروکسی به طور معمول عملیات اضافی قبل یا بعد از شی هدف را انجام میدهد، در حالی که الگوی دکوراتور به طور پویا قابلیتهای اضافی را به شی هدف اضافه میکند.
5.2 مقایسه بین پروکسی استاتیک و پروکسی پویا
الگوی پروکسی را میتوان به پروکسی استاتیک و پروکسی پویا تقسیم کرد. پروکسی استاتیک نوع شی پروکسی را در زمان کامپایل تعیین میکند و شی پروکسی به صورت دستی توسط برنامه نویس نوشته میشود. از سوی دیگر، پروکسی پویا، شی پروکسی را به صورت پویا در زمان اجرا بر اساس رابط شی هدف تولید میکند. پروکسی پویا انعطافپذیرتر است اما نسبت به مقابل استاتیکش پیچیدهتر است.
5.3 کاربرد الگوی پروکسی در معماری میکروسرویس
الگوی پروکسی میتواند در یک معماری میکروسرویس به کار رود. به عنوان مثال، میتوان از یک پروکسی استفاده کرد تا دسترسی به سرویسهای دیگر میکروسرویسها را بستهبندی کرده و مکانیزمهایی مانند توازن بار، محدودیت نرخ و شکست مدار را در لایه پروکسی پیادهسازی کرد. این کار میتواند اعتمادپذیری و عملکرد سیستم را تقویت کند. الگوی پروکسی همچنین برای پیادهسازی کشف سرویس و قابلیت هدایت نیز مورد استفاده قرار میگیرد.