
الگوی طراحـــــــــی Iterator
الگوی طراحی Iterator یک الگوی رایج در برنامهنویسی است که برای گشتن در اجزای مختلف یک مجموعهداده یا یک کالکشن به کار میرود. این الگو اجازه میدهد تا مجموعهداده یا کالکشنی را بدون اینکه نیاز به دسترسی به جزئیات داخلی آن داشته باشیم، به صورت مرتب شده و تکرارپذیر از طریق یک iterator (تکرارکننده) اسکن کنیم.
مفهوم الگوی Iterator به این صورت است که ما یک رابط Iterator داریم که تعیینکنندهی روشهای موردنیاز برای اسکن کردن یک مجموعهداده است. سپس برای هر کالکشن، یک کلاس Iterator مخصوص خود داریم که از رابط Iterator ارثبری میکند و متدهای مربوط به اسکن کردن و دسترسی به عناصر را پیادهسازی میکند.
معمولاً اجزاء اصلی الگوی طراحی Iterator شامل موارد زیر هستند:
1. Iterator (تکرارکننده): رابط یا کلاسی است که متدهای مربوط به اسکن کردن مجموعهداده را تعیین میکند، مانند متدهای Next() برای حرکت به عنصر بعدی، و متدای HasNext() برای بررسی وجود عنصر بعدی.
2. ConcreteIterator (تکرارکنندهی خاص): کلاسی است که از رابط Iterator ارثبری میکند و متدهای مربوط به اسکن کردن مجموعهداده را پیادهسازی میکند.
3. Aggregate (کالکشن): رابط یا کلاسی است که مجموعهداده را تعریف میکند و یک Iterator مناسب برای آن ایجاد میکند.
4. ConcreteAggregate (کالکشن خاص): کلاسی است که از رابط Aggregate ارثبری میکند و متدای مربوط به ایجاد Iterator مخصوص خود را پیادهسازی میکند.
حالا با یک مثال واقعی از الگوی Iterator در زبان سی شارپ آشنا میشویم:
فرض کنید ما یک برنامهی مدیریت فایلها داریم و میخواهیم لیستی از فایلها را نمایش دهیم و بتوانیم به صورت مرتبشده آنها را پیمایش کنیم. در این صورت از الگوی Iterator استفاده میکنیم.
1. Iterator (تکرارکننده):
1public interface IIterator<T>
2{
3 bool HasNext();
4 T Next();
5}
2. ConcreteIterator (تکرارکنندهی خاص):
1public class FileIterator : IIterator<string>
2{
3 private FileCollection _collection;
4 private int _index = 0;
5
6 public FileIterator(FileCollection collection)
7 {
8 _collection = collection;
9 }
10
11 public bool HasNext()
12 {
13 return _index < _collection.Count;
14 }
15
16 public string Next()
17 {
18 if (HasNext())
19 {
20 string file = _collection[_index];
21 _index++;
22 return file;
23 }
24 throw new InvalidOperationException("No more elements available.");
25 }
26}
3. Aggregate (کالکشن):
1public interface IAggregate<T>
2{
3 IIterator<T> CreateIterator();
4}
4. ConcreteAggregate (کالکشن خاص):
1public class FileCollection : IAggregate<string>
2{
3 private List<string> _files = new List<string>();
4
5 public void AddFile(string fileName)
6 {
7 _files.Add(fileName);
8 }
9
10 public IIterator<string> CreateIterator()
11 {
12 return new FileIterator(this);
13 }
14
15 public int Count => _files.Count;
16
17 public string this[int index] => _files[index];
18}
5. Client (کلاینت):
1public class Program
2{
3 public static void Main()
4 {
5 FileCollection fileCollection = new FileCollection();
6 fileCollection.AddFile("document.txt");
7 fileCollection.AddFile("image.jpg");
8 fileCollection.AddFile("video.mp4");
9
10 IIterator<string> iterator = fileCollection.CreateIterator();
11
12 Console.WriteLine("Files in the collection:");
13
14 while (iterator.HasNext())
15 {
16 string file = iterator.Next();
17 Console.WriteLine(file);
18 }
19 }
20}
خروجی برنامه به صورت زیر خواهد بود:
Files in the collection:
document.txt
image.jpg
video.mp4
در این مثال، ما از الگوی Iterator برای پیمایش و نمایش لیستی از فایلها استفاده کردیم. کلاس `FileCollection` که از رابط <IAggregate<string ارث بری میکند، لیستی از فایلها را نمایش میدهد و تابع `CreateIterator()` که به عنوان آرایهی Iterator ایجاد میکند، یک نمونه از کلاس `FileIterator` را برمیگرداند. این تکرارکننده (Iterator) قادر به پیمایش لیست فایلها و نمایش آنها میباشد. با استفاده از الگوی Iterator، ما مجموعهدادهها را از جزئیات داخلی جدا کردهایم و به صورت مرتب و تکرارپذیر به آنها دسترسی داریم.