
الگوی طراحـــــــــی Visitor
الگوی طراحی Visitor یک الگوی رایج در برنامهنویسی است که برای اجازه دادن به یک الگوریتم جدا از اشیاء که بر روی آنها عملیات انجام میدهد، استفاده میشود. این الگو به ما اجازه میدهد که عملیاتهای مختلف را به اشیاء اضافه کنیم بدون اینکه بخواهیم کد خود اشیاء را تغییر دهیم.
مفهوم الگوی Visitor به این صورت است که ما یک کلاس Visitor داریم که تعدادی متد مشخصی را برای بازدید از اشیاء تعریف میکند. سپس کلاسهای مختلفی وجود دارند که این Visitor را به عنوان ویژگی دریافت میکنند. این کلاسها معمولاً بازدید از اشیاء را در متدهای خود انجام میدهند.
الگوی Visitor به ما امکان میدهد عملیاتهای جدید را بر روی اشیاء بدون تغییر کلاسهای آنها اضافه کنیم. این به ما اجازه میدهد که اصول مهم طراحی مانند اصل "Open/Closed" و "Single Responsibility" را در طراحی برنامهمان رعایت کنیم.
برای درک بهتر این الگو، با یک مثال ملموس و کاربردی در دنیای واقعی آشنا میشویم:
فرض کنید ما یک برنامه برای مدیریت فایلها داریم. در این برنامه، فایلها میتوانند نوعهای مختلفی مانند فایلهای متنی، فایلهای تصویری و فایلهای ویدئویی باشند. ما میخواهیم یک عملیات مشترک برای همهی این فایلها را انجام دهیم، مانند نمایش اطلاعات فایلها. با استفاده از الگوی Visitor، میتوانیم این عملیات را جدا از کلاسهای فایلها تعریف کنیم.
برای حل این مشکل و استفاده از کد موجود در برنامه، میتوانیم از الگوی Adapter استفاده کنیم. برای این منظور، یک Adapter به نام `AudioPlayerAdapter` ایجاد میکنیم که از `IMediaPlayer` ارثبری میکند و قابلیت پخش فایلهای صوتی را به آن اضافه میکنیم. این Adapter وظیفه تبدیل درخواستهای مرتبط با پخش فایلهای صوتی به فرمتهای قابل قبول توسط `IMediaPlayer` را دارد.
حالا بیایید کد مربوط به این مثال را در زبان سی شارپ بنویسیم:
1. Visitor:
1public interface IFileVisitor
2{
3 void VisitTextFile(TextFile file);
4 void VisitImageFile(ImageFile file);
5 void VisitVideoFile(VideoFile file);
6}
2. Element (قابل بازدید):
1public abstract class File
2{
3 public abstract void Accept(IFileVisitor visitor);
4 // دیگر متدهای مختص کلاسهای فایل اینجا تعریف میشوند.
5}
3. ConcreteElement (کلاسهای فایلها):
1public class TextFile : File
2{
3 public override void Accept(IFileVisitor visitor)
4 {
5 visitor.VisitTextFile(this);
6 }
7
8 // متدها و ویژگیهای مختص این کلاس اینجا تعریف میشوند.
9}
10
11public class ImageFile : File
12{
13 public override void Accept(IFileVisitor visitor)
14 {
15 visitor.VisitImageFile(this);
16 }
17
18 // متدها و ویژگیهای مختص این کلاس اینجا تعریف میشوند.
19}
20
21public class VideoFile : File
22{
23 public override void Accept(IFileVisitor visitor)
24 {
25 visitor.VisitVideoFile(this);
26 }
27
28 // متدها و ویژگیهای مختص این کلاس اینجا تعریف میشوند.
29}
4. ConcreteVisitor (ویژیتور واقعی):
1public class FileInformationVisitor : IFileVisitor
2{
3 public void VisitTextFile(TextFile file)
4 {
5 Console.WriteLine($"File Type: Text File, Size: {file.Size} KB");
6 }
7
8 public void VisitImageFile(ImageFile file)
9 {
10 Console.WriteLine($"File Type: Image File, Resolution: {file.Resolution}");
11 }
12
13 public void VisitVideoFile(VideoFile file)
14 {
15 Console.WriteLine($"File Type: Video File, Duration: {file.Duration} seconds");
16 }
17}
5. Client (کلاینت):
1public class Program
2{
3 public static void Main()
4 {
5 List<File> files = new List<File>
6 {
7 new TextFile { Size = 1024 },
8 new ImageFile { Resolution = "1920x1080" },
9 new VideoFile { Duration = 360 }
10 };
11
12 FileInformationVisitor visitor = new FileInformationVisitor();
13 foreach (var file in files)
14 {
15 file.Accept(visitor);
16 }
17 }
18}
خروجی برنامه به صورت زیر خواهد بود:
File Type: Text File, Size: 1024 KB
File Type: Image File, Resolution: 1920x1080
File Type: Video File, Duration: 360 seconds
در این مثال، با استفاده از الگوی Visitor، ما یک برنامه برای مدیریت فایلها ایجاد کردیم. بازدیدکننده FileInformationVisitor عملیات نمایش اطلاعات فایلها را برای کلاسهای فایلها انجام میدهد و این عملیات از کلاسهای فایلها جدا شده است. با این روش، میتوانیم به راحتی عملیاتهای جدیدی را برای فایلها اضافه کنیم بدون اینکه بخواهیم کدهای اصلی کلاسهای فایلها را تغییر دهیم.