اخبار، مطالب و رویدادهای مرتبط با توسعه نرم افزار رادکام

الگوی طراحی پروکسی (Proxy)

نقش و وظیفه الگوی طراحی پروکسی

الگوی طراحی Proxy برای ایجاد اشیایی استفاده می شود که در اصل آنها ایجاد و دسترسی به اشیاء دیگر را کنترل می کنند. پروکسی غالباً یک شیء کوچک (عمومی) است که به دنبال یک موضوع پیچیده تر (خصوصی) می رود که به مجرد مشخص شدن و اتفاق افتادن شرایط خاص فعال می شود.

تصویر کلی الگوی طراحی پروکسی

یکی از پدیده های مهم در جهان امروز افزایش محبوبیت سیستم های شبکه های اجتماعی است که شاید یکی از برجسته ترین آن ها فیسبوک باشد. شکل زیر را به عنوان صفحه ای از فیس بوک در نظر می گیریم.

تصویر قدیمی فیسبوک - الگوی طراحی پروکس

از ویژگی های چنین سیستمهایی این است که بسیاری از افرادی که ثبت نام می کنند، به دنبال این هستند که ببینند دیگران چه کار می کنند و خود به طور فعال در این فعالیت ها شرکت نمی کنند و محتوایی هم اضافه نمی کنند. بنابراین ممکن است این یک سیاست خوب برای شروع یک تازه کار باشد، که شخص یک صفحه ساده داشته باشد و تا زمانی که شروع به فعالیت در سیستم نکند، (مانند اضافه کردن دوستان و ارسال پیام و قرار دادن مطلب) اجازه دسترسی به فضای ذخیره سازی واقعی به ایشان داده نشود، و همچنین اجازه دسترسی به امکانات سیستم به او داده نشود.
ویژگی دیگر این نوع سیستم ها و سیستم های مشابه این است که ابتدا باید در سیستم مورد نظر ثبت نام کنید و سپس برای دسترسی به آن وارد سیستم بشوید. پس از ورود به سیستم به صفحات عمومی دوستان خود دسترسی پیدا خواهید کرد. کلیه کارهایی که یک شخص می تواند انجام دهد، مانند نوشتن مطلب، نوشتن دیوارنوشت، ارسال فایل و غیره، از طریق مرورگر سیستم شما شروع می شود و سپس از طریق شبکه به نزدیکترین سرور فیسبوک ارسال می شود. در اینجا اشیا در اصل صفحات فیسبوک هستند، پروکسی ها می توانند مکانیزمی باشند که امکان ثبت نام و ورود به سیستم را فراهم می کنند.

دیاگرام UML الگوی طراحی پروکسی

دیاگرام یو ام ال زیر، نحوه طراحی الگوی پروکسی و اعضای موثر آن را نشان می دهد.

UML دیاگرام الگوی طراحی پروکسی

عناصر اصلی این دیاگرام عبارتند از:
ISubject: یک اینترفیس مشترک برای کلاس های Subject و Proxy که امکان استفاده از آنها را به طور متقابل فراهم می کند.
Subject:  کلاسی که پروکسی نقش ارایه کردن آن را به عهده می گیرد.
Proxy: کلاسی که دسترسی به کلاس Subject را، ایجاد، کنترل، تغییر، تقویت و اعتبارسنجی می کند.
Request: عملی در کلاس Subject که از طریق کلاس Proxy به آن دسترسی خواهیم داشت.

کلاس مرکزی یا همان کلاس Proxy، اینترفیس ISubject را پیاده سازی می کند. مشتری می تواند به جای استفاده از کلاس Proxy از اینترفیس ISubject برای انتزاع (تجرید) از کلاس Proxy استفاده کند. با این حال، همانطور که در مثال بعدی خواهیم دید، گاهی اوقات می توانیم با همین رابط کاربری عملیات مورد نظر خود را تعریف کنیم. هر شیء پروکسی، یک ارجاع به کلاس Subject ای دارد که عملیات واقعی مورد نظر ما در آن انجام می گیرد. پروکسی در حقیقت کارهای لایه بیرونی را انجام می دهد.   با ایجاد کلاس Subject به صورت یک کلاس private، دسترسی به این کلاس محدود شده و ارزش این کلاس ارتقاء می یابد، به همین دلیل نیز، مشتری و استفاده کننده از این کلاس تنها از طریق کلاس Proxy به آن دسترسی خواهد داشت.

الگوی های پروکسی متعددی وجود دارد که به رایج ترین آنها اشاره می کنیم:
پروکسی مجازی (Virtual Proxies):
ایجاد یک شیء را به یک شیء دیگر واگذار می کند. یعنی در حقیقت ایجاد یک شیء را از طریق یک شیء دیگر انجام می دهد. ( این پروکسی زمانی کاربرد دارد که روند ایجاد شیء اصلی کند بوده و یا غیر ضروری باشد.)
پروکسی تایید اعتبار (Authentication Proxies):
مجوز های دسترسی به یک درخواست یا کلاس را بررسی می کند.
پروکسی از راه دور(Remote Proxies):
درخواست ها را رمزگذاری کرده و از طریق شبکه ارسال می کند.
پروکسی هوشمند (Smart Proxies):
قبل از ارسال درخواست ها، آنها را تغییر داده و یا مواردی را به آنها اضافه می کند.

اگر شبکه های اجتماعی را در نظر بگیریم، کاربرد انواع پروکسی در این سیستم ها به صورت زیر می تواند باشد.
  • ایجاد تاخیر در ایجاد کلاس های اصلی و سنگین (پروکسی مجازی)
  • سیستم ورود کاربران (پروکسی اعتبار سنحی)
  • ارسال درخواست از طریق شبکه (پروکسی از راه دور)
  • انجام عملیات لازم روی برخی از اطلاعات دوستان در شبکه (پروکسی هوشمند)

پیاده سازی الگوی طراحی Proxy:


شاید یکی از اهداف اصلی چنین مقالاتی، معرفی ویژگی های جالب سی شارپ باشد و اینکه این ویژگی ها چگونه باعث می شوند الگوهایی آسان تر ، واضح تر و ایمن تر بنویسیم. هر ویژگی معمولا جای خود را در یک الگو پیدا می کند، در مثال زیر نیز یک کاربرد از Access Modifiers (تغییر دهنده دسترسی، تنظیم کننده سطح دسترسی) را خواهیم دید.
ابتدا اشاره ای به Access Modifier ها در جدول زیر می کنیم:

تعیین کننده دسترسی تاثیر پیش فرض برای
private در متد یا نوعی که در آن اعلام شده است قابل دسترس است اعضای کلاسها و استراکت ها؛ انواع تو در تو
internal در داخل اسمبلی قابل دسترسی است انواع غیر تو در تو
protected در یک کلاس و کلاسهای مشتق شده آن قابل دسترسی است -
protected internal در یک کلاس ، کلاسهای مشتق شده آن یا  اسمبلی قابل دسترسی است -
public در همه جا قابل دسترسی است Enumartion ها و رابط ها

حال، بیایید به یک مثال نظری کوچک از الگویی که هدف آن نشان دادن موارد زیر است نگاهی بیاندازیم:
چگونه یک ارتباط بین کلاینت در یک سو و پروکسی و Subject در یک سوی دیگر، با سختگیرانه ترین و دقیق ترین تعیین کننده های سطوح دسترسی تعریف می شود.
چگونه پروکسی های مجازی و حفاظتی، درخواست های رسیده به آنها را انجام می دهند.
اصلی ترین کد پروکسی مجازی این است:

		
public class Proxy : ISubject
{
	Subject subject;
	public string Request() 
	{
		// A virtual proxy creates the object only on its first method call
		if (subject == null)
			subject = new Subject();
		return subject.Request();
	}
}

کلاینت هر زمان که بخواهد می تواند با ایجاد یک نوع از پروکسی، از آن استفاده کند. از آنجایی که از یک ایجاد کننده (Constructor) پیش فرض استفاده می شود، ارجاع به کلاس Subject در این لحظه ایجاد نمی شود. و فقط زمانی که متد Request فراخوانی می شود، ارجاع به کلاس Subject بررسی می شود، اگر Null باشد، یک نمونه شی از آن ایجاد می شود.
کد کامل مثال اشاره شده در زیر آورده شده است، این مثال بر این نکته تاکید دارد که تمام نمونه های موجود ایجاد شده توسط کلاینت، از نوع اینترفیس ISubject می باشند. این بدان معنی است که، برای دسترسی به عملیات مازاد و اضافه در کلاس پروکسی، مانند اعتبار سنجی،  باید از کلاس ISubject نمونه سازی کنیم. در مثال زیر پروکسی دومی نیز به نام ProtectionProxy وجود دارد. این پروکسی مستقل از پروکسی ابتدایی است، زمانی که شیء ای از کلاس ProtectionProxy ایجاد می شود. تمام درخواست های ابتدایی با دستورالعمل های احراز هویت برآورده و اجرا می شوند. در این مثال، احراز هویت یک متدی مستقل و جداگانه است که باید فراخوانی شود. در مثال بعدی،  ثبت نام و تایید اعتبار بعد از فراخوانی درخواست به صورت خودکار شروع می شود.

		
using System;

// Proxy Pattern Judith Bishop Dec 2006
// Shows virtual and protection proxies

class SubjectAccessor {
	public interface ISubject {
		string Request();
	}

	private class Subject {
		public string Request() {
			return "Subject Request " + "Choose left door\n";
		}
	}

	public class Proxy : ISubject {
		Subject subject;

		public string Request() {
			// A virtual proxy creates the object only on its first method call
			if (subject == null) {
				Console.WriteLine("Subject inactive");
				subject = new Subject();
			}
			Console.WriteLine("Subject active");
			return "Proxy: Call to " + subject.Request();
		}
	}

	public class ProtectionProxy : ISubject {
		// An authentication proxy first asks for a password
		Subject subject;
		string password = "Abracadabra";

		public string Authenticate (string supplied) {
			if (supplied!=password)
				return "Protection Proxy: No access";
			else
				subject = new Subject();
			return "Protection Proxy: Authenticated";
		}

		public string Request() {
			if (subject==null)
				return "Protection Proxy: Authenticate first";
			else return "Protection Proxy: Call to "+
				subject.Request();
		}
	}
}

class Client : SubjectAccessor {
	static void Main() {
		Console.WriteLine("Proxy Pattern\n");

		ISubject subject = new Proxy();
		Console.WriteLine(subject.Request());
		Console.WriteLine(subject.Request());

		ProtectionProxy subject = new ProtectionProxy();
		Console.WriteLine(subject.Request());
		Console.WriteLine((subject as ProtectionProxy).Authenticate("Secret"));
		Console.WriteLine((subject as ProtectionProxy).Authenticate("Abracadabra"));
		Console.WriteLine(subject.Request());
	}
}

/* Output

Proxy Pattern

Subject inactive
Subject active
Proxy: Call to Subject Request Choose left door

Subject active
Proxy: Call to Subject Request Choose left door

Protection Proxy: Authenticate first
Protection Proxy: No access
Protection Proxy: Authenticated
Protection Proxy: Call to Subject Request Choose left door
*/
این برنامه با یک کلاس به نام SubjectAccessor محصور شده است، که این کار برای گروه بندی کلاس های پروکسی و  Subject انجام شده است. اینترفیس و کلاس های پروکسی همه به صورت public تعریف شده اند، بنابراین، خود آنها و اعضای آنها که به صورت عمومی تعریف شده اند، همه به طور کامل در دسترس کلاینت (برنامه استفاده کننده) قرار می گیرند.  هدف از ایجاد کلاس های پروکسی Virtual و Protected ایجاد یک دسترسی مشخص به کلاس Subject است. به همین دلیل است که کلاس Subject به صورت private تعریف شده است و متد Request آن public است، اما این متد فقط برای کلاس هایی قابل دسترس است که می توانند خود کلاس را ببینند، مانند کلاس های داخل SubjectAccessor.
ما می توانیم دو آزمایش انجام دهیم تا بررسی کنیم و ببینیم که قابلیت های دسترسی تعریف شده درست است یا نه:

یک گروه بندی عمومی تر برای کلاس های پروکسی و Subject می تواند Namespace هایی باشد که تعریف می کنیم، اما کلاس هایی که درون NameSpace ها قرار دارند نمی توانند به صورت private تعریف شوند.
کد زیر را به متد main اضافه کنید:

ISubject test = new Subject();

کدی که در سمت کلاینت نوشته شده است کامپایل نخواهد شد، زیرا کد های برنامه به گونه ای نوشته شده است که فقط می توانیم از کلاس های Proxy نمونه بسازیم. با این حال اگر خاصیت private بودن کلاس Subject را حذف کنیم می توانیم از آن نیز نمونه بسازیم. دلیل این کار این است که برای دستری به کلاس های موجود در SubjectAccessor، کلاینت از آنها ارث بری می کند، و با این کار به اعضای داخلی آن دسترسی پیدا می کنند.  یک روش جایگزین برای برنامه نوشته شده ، در یک تمرین پیش رو ، مورد بحث قرار خواهد گرفت.
همانطور که بحث مطرح شده نشان داد، شما می توانید سطوح دسترسی کلاس های پروکسی و Subject را آنگونه که مورد نیازتان  است تعریف کنید. قرار نیست این کلاس ها به طور کامل مستقل از هم باشند، از این روست که درون یک کلاس گروه بندی شده اند.  پروکسی ها آزادند که بین کلاس های Subject پیوند و ارتباط مورد نیاز را ایجاد کنند. پروکسی ها  کلاس های Subject را به طور هماهنگ با هم و با آنچه به کلاینت ارایه می دهند، حفظ می کنند.

مثال: Spacebook

برای تحقیق و بررسی بیشتر در زمینه پروکسی ها، ما یک سیستم شبکه اجتماعی جدی را با نام Spacebook فرض می کنیم. برنامه Spacebook، صفحات متنی ای را که افراد تحت نام کاربری خود وارد می کنند نگهداری می کند، بنابراین، احراز هویت کاربران و ایجاد صفحات با مکانیزم Lazy Loading مورد نیاز است. همانطور که در بخش قبلی مشاهده کردید، ثبت نام صرف درون برنامه Spacebook، هیچ فضایی را درون سیستم برای کاربران در اختیار قرار نخواهد داد، برای دریافت فضای ذخیره سازی اطلاعات و مطالب، ابتدا باید یک مطلب در سیستم ایجاد و به سیستم اضافه کنند. بنابراین ، سیستم از ابتدا باید افراد را قادر به نوشتن در صفحات دیگران کند. کلاس Spacebook می تواند چیزی شبیه کلاس زیر باشد:


private class SpaceBook 
{
	static SortedList< string,RealSpaceBook> community = new SortedList< string,RealSpaceBook>(100);
	string pages;
	string name;
	string gap = "\n\t\t\t\t";
	static public bool IsUnique (string name) 
	{
		return community.ContainsKey(name);
	}
	
	internal SpaceBook (string n) 
	{
		name = n;
		community [n] = this;
	}

	internal void Add(string s) 
	{
		pages += gap+s;
		Console.WriteLine(gap+"======== "+name+"'s SpaceBook =========");
		Console.WriteLine(pages);
		Console.WriteLine(gap+"==========================");
	}
	
	internal void Add(string friend, string message) 
	{
		community[friend].Add(message);
	}
	
	internal void Poke (string who, string friend) 
	{
		community[who].pages += gap + friend + " poked you";
	}
}

کلاس Spacebook فهرستی استاتیک از همه کاربران فعلی را نگهداری می کند. ما از کلاس از پیش تعبیه شده SortedList که در فضای نام System.Collections.Generic قرار دارد استفاده می کنیم و یک فهرست از اعضا و نام کاربر به عنوان یک رشته متنی (string) ایجاد می کنیم. در متد سازنده کلاس می بینیم که شیء Spacebook  در یک Collection با نام داده شده به عنوان پارامتر متد سازنده قرار گرفته است. دو متذ Add نیز وجود دارد که: یکی برای اضافه کردن کاربر و دیگری برای اضافه کردن صفحات کاربر. سپس متد محبوب poke قرار دارد که یک پیام ثابت را در صفحه یک کاربر دیگر درج می کند.

کلاس Spacebook یک متد public دارد که شاید وجود آن غیر منتظره و عجیب به نظر برسد. متد استاتیک Unique، که بررسی می کند که یک اسم قبلا مورد استفاده قرار گرفته است یا نه. این متد ما را قادر می سازد که فهرست انجمن ها را به طور کامل خصوصی نگهداری کنیم(که به طور پیش فرض درون کلاس است). حال به سراغ کلاینت می رویم. کلاینت چند تا فعالیت را توسط  Tom و Judith انجام می دهد.

		
// The Client
class ProxyPattern : SpaceBookSystem 
{
	static void Main ( ) 
	{
		MySpaceBook me = new MySpaceBook( );
		me.Add("Hello world");
		me.Add("Today I worked 18 hours");
		MySpaceBook tom = new MySpaceBook( );
		tom.Poke("Judith");
		tom.Add("Judith","Poor you");
		tom.Add("Off to see the Lion King tonight");
	}
}		
اولین کاربر، که ما از Judith استفاده می کنیم، یک MySpaceBook (نه یک SpaceBook) را ایجاد کرده، دو پیام به آن اضافه می کند. سپس تام نیز یک MySpaceBook ایجاد کرده و یک اشاره به Judith می کند و  سپس یک پیام به صفحه Judith و یک پیام به صفحه خودش اضافه می کند. توجه داشته باشید که نه کلاینت و نه سیستم اصلی SpaceBook هیچ کدی برای اعتبار سنجی ندارند. این کار فقط در Proxy اتفال می افتد که در اینجا به وضوح مشخص است که همان کلاس MySpaceBook است. خروجی کد کلاینت قبلی چنین خواهد بود:

Let's register you for SpaceBook
All SpaceBook names must be unique
Type in a user name: Judith
Type in a password: haha
Thanks for registering with SpaceBook
Welcome Judith. Please type in your password: haha
Logged into SpaceBook

======== Judith's SpaceBook =========
Hello world
==================================
======== Judith's SpaceBook =========
Hello world
Today I worked 18 hours
==================================	

Let's register you for SpaceBook All SpaceBook names must be unique Type in a user name: Tom Type in a password: yey Thanks for registering with SpaceBook Welcome Tom. Please type in your password: yey Logged into SpaceBook ======== Judith's SpaceBook ========= Hello world Today I worked 18 hours Tom poked you eTom said: Poor you ================================== ======== Tom's SpaceBook ========= Off to see the Lion King tonight ==================================
ما می توانیم بین خروجی که خود کلاس SpaceBook تولید می کند و درون خطوط کشیده شده قرار گرفته است و همچنیم فعل و انفعلاتی که توسط کلاس های Proxy صورت گرفته است تمایز قائل شویم. کلاس SpaceBook متد سازنده ای ندارد. جدا از گرفتن مرجع از کلاس، وقتی کلاینت یک نمونه از Spacebook را ایجاد می کند، اتفاقی در برنامه نمی افتد. قلب تپنده کلاس Proxy در بخش زیر است:

public void Add(string message) 
{
	Check( );
	if (loggedIn) mySpaceBook.Add(message);
}

void Check( ) 
{
	if (!loggedIn) 
	{
		if (password==null)
			Register( );
		if (mySpaceBook == null)
			Authenticate( );
	}
}
اولین نقطه ارتباط با کلاینت، استفاده از متد Add است. متد Add بلادرنگ وضعیت کاربر را بررسی می کند، و کاربر را در مسیر ثبت نام و تخصیص رمز عبور راهنمایی می کند، و سپس عمل احراز هویت را با استفاده از رمز عبور ارایه شده انجام می دهد. متد Check نیز توسط یک متد Add و Pock دیگری فراخوانی می شود. حال بعد از این همه توضیح و تعریف، می توانیم کل کد ها را یکجا داشته باشیم.

		
using System;
using System.Collections.Generic;
// Proxy Pattern Example Judith Bishop Aug 2007
// Sets up a SpaceBook page with registration and authentication
class SpaceBookSystem 
{
	// The Subject
	private class SpaceBook 
	{
		static SortedList <string,spacebook> community = new SortedList <string,spacebook> (100);
		string pages;
		string name;
		string gap = "\n\t\t\t\t";
		static public bool IsUnique (string name) {
		return community.ContainsKey(name);
	}
	
	internalSpaceBook (string n) 
	{
		name = n;
		community [n] = this;
	}

	internal void Add(string s) 
	{
		pages += gap+s;
		Console.Write(gap+"======== "+name+"'s SpaceBook =========");
		Console.Write(pages);
		Console.WriteLine(gap+"===================================");
	}

	internal void Add(string friend, string message) 
	{
		community[friend].Add(message);
	}

	internal void Poke (string who, string friend) 
	{
		community[who].pages += gap + friend + " poked you";
	}
}


// The Proxy
public class MySpaceBook 
{
	// Combination of a virtual and authentication proxy
	SpaceBook mySpaceBook;
	string password;
	string name;
	bool loggedIn = false;
	void Register ( ) 
	{
		Console.WriteLine("Let's register you for SpaceBook");
		do 
		{
			Console.WriteLine("All SpaceBook names must be unique");
			Console.Write("Type in a user name: ");
			name = Console.ReadLine( );
		} while (SpaceBook.Unique(name));
		
		Console.Write("Type in a password: ");
		password = Console.ReadLine( );
		Console.WriteLine("Thanks for registering with SpaceBook");
	}
	
	bool Authenticate ( ) 
	{
		Console.Write("Welcome "+name+". Please type in your password: ");
		string supplied = Console.ReadLine( );
		if (supplied==password) 
		{
			loggedIn = true;
			Console.WriteLine("Logged into SpaceBook");
			if (mySpaceBook == null)
			mySpaceBook = new SpaceBook(name);
			return true;
		}
		
		Console.WriteLine("Incorrect password");
		return false;
	}

	public void Add(string message) 
	{
		Check( );
		if (loggedIn) mySpaceBook.Add(message);
	}
	
	public void Add(string friend, string message) 
	{
		Check( );
		if (loggedIn)
		mySpaceBook.Add(friend, name + " said: "+message);
	}

	public void Poke(string who) 
	{
		Check( );
		if (loggedIn)
		mySpaceBook.Poke(who,name);
	}
	
	void Check( ) 
	{
		if (!loggedIn) 
		{
			if (password==null)
				Register( );
			if (mySpaceBook == null)
				Authenticate( );
		}
	}
}

// The Client
class ProxyPattern : SpaceBookSystem 
{
	static void Main ( ) 
	{
		MySpaceBook me = new MySpaceBook( );
		me.Add("Hello world");
		me.Add("Today I worked 18 hours");
		MySpaceBook tom = new MySpaceBook( );
		tom.Poke("Judith");
		tom.Add("Judith","Poor you");
		tom.Add("Off to see the Lion King tonight");
	}
}


/* Output
Let's register you for SpaceBook
All SpaceBook names must be unique
Type in a user name: Judith
Type in a password: haha
Thanks for registering with SpaceBook
Welcome Judith. Please type in your password: haha
Logged into SpaceBook
======== Judith's SpaceBook =========
Hello world
==================================
======== Judith's SpaceBook =========
Hello world
Today I worked 18 hours
==================================
Let's register you for SpaceBook
All SpaceBook names must be unique
Type in a user name: Tom
Type in a password: yey
Thanks for registering with SpaceBook
Welcome Tom. Please type in your password: yey
Logged into SpaceBook
======== Judith's SpaceBook =========
Hello world
Today I worked 18 hours
Tom poked you
eTom said: Poor you
==================================
======== Tom's SpaceBook =========
Off to see the Lion King tonight
==================================
*/</string,spacebook></string,spacebook>	
توجه کنید که در این برنامه نیازی به اینترفیس ISubject وجود ندارد. کلاس های SpaceBook و MySpaceBook که درون SpaceBookSystem استقرار دارند، تعامل مابین کلاس ها و متد ها را توسط  تنظیم کننده های سطوح دسترسی و عمل تجمیع (کلاس MySpaceBook یک ارجاع به کلاس SpaceBook دارد) انجام می دهند.

کاربرد الگوی پروکسی

پروکسی ها یک کلاس مقدماتی برای کلاس های دیگری هستند که اطلاعات و متد های حساسی دارند و یا کار با آنها با صورت مستقیم ممکن است باعث کندی عملکرد سیستم گردد. پروکسی ها اغلب در سیستم های طراحی تصویر به چشم می خورند، در این سیستم ها، کلاس پروکسی ابتدا یک تصویر نمادین بیرونی در صفحه نمایش می دهد و سپس کلاس ترسیم کننده تصویر را فعال کرده، اطلاعات تصویر را دریافت و تصویر اصلی را رسم می کند. و به همین روش کلاس های پروکسی،  قادر هستند در مکانیزم های بافر کردن فیلم ها و پخش آنها نقش عمده ای بازی کنند.
کلاس های پروکسی مانند کلاس های دکوراتور درخواست ها را به یک شیء دیگری ارسال می کند. تفاوت آن با دکوراتور این است که رابطه پروکسی به کلاس اصلی زمان طراحی ایجاد شده است، و از قبل مشخص است، حتی اگر نقش کلاس Subject را به عنوان مشارکت کننده فعال در این رابطه قلمداد نکنیم. از طرف دیگر کلاس های دکوراتور به صورت پویا به برنامه اضافه می شوند.
از کلاس پروکسی زمانی استفاده می کنیم که...
ما اشیائی داریم که:
  • ایجاد آنها هزینه سنگینی به سیستم اعمال می کند.
  • نیاز هست تا مکانیزم کنترل دسترسی به اشیاء اصلی پیاده سازی کنیم.
  • نیاز هست به اشیاء ریموت (از راه دور) دسترسی پیدا کنیم.
  •  عملیاتی را در سیستم انجام دهیم که فقط در زمان دسترسی به اشیاء باید اتفاق بی افتند.
و یا می خواهیم:
  • یک سری اشیاء را فقط زمانی ایجاد کنیم که عملیات و متد های داخل آنها فراخوانی می شوند.
  • نیاز داریم تا زمان دسترسی به اشیاء مورد نظر، یک سری بررسی هایی را انجام دهیم.
  • سطوح دسترسی خاصی را روی اشیاء، به هنگام دسترسی به متد های داخل آنها تعریف کنیم.

منبع:

C# 3.0 Design Patterns - Ebook

پست های مرتبط

نام را وارد کنید
تعداد کاراکتر باقیمانده: 1000
نظر خود را وارد کنید