همه کاربران کامپیوتر در ایران به خوبی با کلمه پروکسی آشنا هستند. پروکسی به معنی نماینده یا واسط است و پروکسی واسطی است بین ما و شیء اصلی. پروکسی در شبکه به این معنی است که سیستم شما به یک سیستم واسط متصل شده است که از طریق پروکسی محدودیتهای دسترسی برای آن تعریف شود. در اینجا هم پروکسی در واقع به همین منظور استفاده میشود. در تعدادی از کامنتهای سایت خوانده بودم دوستان در مورد اصول SOLID و Refactoring بحث میکردند که آیا انجام عمل اعتبارسنجی در خود اصل متد کار درستی است یا خیر. در واقع خودم هم نمیدانم که این حرکت چقدر به این اصول پایبند است یا خیر، ولی میدانم که الگوی پروکسی کل سؤالات بالا را حذف میکند و با این الگو دیگر این سؤال اهمیتی ندارد. به عنوان مثال فرض کنید که شما یک برنامه ساده کار با فایل را دارید. ولی اگر بخواهید اعتبارسنجیهایی را برای آن تعریف کنید، بهتر است اینکار را به یک پروکسی بسپارید تا شیء گرایی بهتری را داشته باشید.
برای شروع ابتدا یک اینترفیس تعریف میکنیم:
این اینترفیس شامل سه متد نام نویسی، حذف فایل و دریافت اطلاعات یک دایرکتوری است. بعد از آن دو عدد کلاس را از آن مشتق میکنیم:
کلاس اصلی:
که تنها وظیفه اجرای فرامین را دارد و دیگری کلاس پروکسی است که وظیف تامین اعتبارسنجی و آماده سازی پیش شرطها را دارد:
کلاس پروکسی، همان کلاسی است که شما باید صدا بزنید. وظیفه کلاس پروکسی هم این است که در زمان معین و صحیح، کلاس اصلی شما را بعد از اعتبارسنجیها و انجام پیش شرطها صدا بزند. همانطور که میبیند، ما در سازنده کلاس اصلی را در حافظه قرار میدهیم. سپس در هر متد، اعتبارسنجیهای لازم را انجام میدهیم. مثلا در متد GetDirectoryInfo باید اطلاعات دایرکتوری بازگشت داده شود؛ ولی اصل عمل در واقع در کلاس اصلی است و اینجا فقط شرط گذاشتهایم اگر مسیر داده شده معتبر نبود، همان مسیر را ایجاد کن و سپس متد اصلی را صدا بزن. یا اگر فایل موجود است جهت حذف آن اقدام کن و ...
در نهایت در بدنه اصلی با تست چندین حالت مختلف، همه متدها را داریم:
و نتیجه خروجی:
برای شروع ابتدا یک اینترفیس تعریف میکنیم:
public interface IFilesService { DirectoryInfo GetDirectoryInfo(string directoryPath); void DeleteFile(string fileName); void WritePersonInFile(string fileName,string name, string lastName, byte age); }
کلاس اصلی:
class FilesServices:IFilesService { public DirectoryInfo GetDirectoryInfo(string directoryPath) { return new DirectoryInfo(directoryPath); } public void DeleteFile(string fileName) { File.Delete(fileName); Console.WriteLine("the file has been deleted"); } public void WritePersonInFile(string fileName, string name, string lastName, byte age) { var text = $"my name is {name} {lastName} with {age} years old from dotnettips.info"; File.WriteAllText(fileName,text); } }
class FilesServicesProxy:IFilesService { private readonly IFilesService _filesService; public FilesServicesProxy() { _filesService=new FilesServices(); } public DirectoryInfo GetDirectoryInfo(string directoryPath) { var existing = Directory.Exists(directoryPath); if (!existing) Directory.CreateDirectory(directoryPath); return _filesService.GetDirectoryInfo(directoryPath); } public void DeleteFile(string fileName) { if(!File.Exists(fileName)) Console.WriteLine("Please enter a valid path"); else _filesService.DeleteFile(fileName); } public void WritePersonInFile(string fileName, string name, string lastName, byte age) { if (!Directory.Exists(fileName.Remove(fileName.LastIndexOf("\\")))) { Console.WriteLine("File Path is not valid"); return; } if (name.Trim().Length == 0) { Console.WriteLine("first name must enter"); return; } if (lastName.Trim().Length == 0) { Console.WriteLine("last name must enter"); return; } if (age<18) { Console.WriteLine("your age is illegal"); return; } if (name.Trim().Length < 3) { Console.WriteLine("first name must be more than 2 letters"); return; } if (lastName.Trim().Length <5) { Console.WriteLine("last name must be more than 4 letters"); return; } _filesService.WritePersonInFile(fileName,name,lastName,age); Console.WriteLine("the file has been written"); } }
در نهایت در بدنه اصلی با تست چندین حالت مختلف، همه متدها را داریم:
static void Main(string[] args) { IFilesService filesService=new FilesServicesProxy(); filesService.WritePersonInFile("c:\\myfakepath\\a.txt","ali","yeganeh",26); var directory = filesService.GetDirectoryInfo("d:\\myrightpath\\"); var fileName = Path.Combine(directory.FullName, "dotnettips.txt"); filesService.WritePersonInFile(fileName, "al", "yeganeh", 26); filesService.WritePersonInFile(fileName, "ali", "yeganeh", 12); filesService.WritePersonInFile(fileName, "ali", "yeganeh", 26); filesService.DeleteFile("c:\\myfakefile.txt"); filesService.DeleteFile(fileName); }
File Path is not valid first name must be more than 2 letters your age is illegal the file has been written Please enter a valid path the file has been deleted