Merhabalar,
Bir önceki makalemizde Davranışsal Tasarım Desenlerinden State Pattern üzerinde durmuştuk. Şimdi yine Davranışsal Tasarım Desenlerinden Iterator Pattern(öteleyici tasarım deseni) üzerinde durmaya çalışacağım.
Öncelikle Iterator Design Pattern(Yineliyici Tasarım Kalıbı) nedir bunu incelemekte fayda var.
Iterator Pattern, dizilerde veya koleksiyonlarda nesnelerin elemanlarına ulaşılması, bu dizilerde veya koleksiyonlar içerisinde dolaşılması, dolaşılması sırasında işlem durursa nerede durduğunun tutulması, tekrar devam edilmesi gerektiğinde nasıl devam edeceğini bilmesi ve bir sonraki nesnenin hangisi olacağının bilinmesi gibi durumları yerine getiren bir tasarım kalıbıdır.
Bu kalıbı aslında farkında olmadan kullanmaktayız fakat bu kalıbın Itarator tasarım kalıbı olduğunun çoğu zaman farkında bile değiliz. Nasıl mı kullanıyoruz? Koleksiyonlar içerisinde dolaşmak için for,while, foreach gibi kullandığımız yapıların temelinde bu tasarım kalıbı kullanılmaktadır. Bu şekilde bir list içerisinde for, foreach veya while gibi yapılarla dönemk istdiğimizde bizim yerimize bu kalıpları otomatik olarak kullanmış olmaktayız.
Iterator Pattern, genel olarak incelendiğinde aşağıdaki UML diyagramına sahip olan bir yapı mevcuttur.

Iterator arayüzü içerisinde bu arayüzden türeyen sınıfların kullanacağı ve sorumlu olduğu operasyonları bildirmektedir. Yukarıda da belirttiğimiz gibi işlem içerisinde hangi aşamada olduğunu ve hangi nesneyi kullandığını gösteren CurrentItem adında bir metod veya property vardır. Bir sonraki aşamaya geçmek için MoveNext metodu, daha sonra herhangi bir nesne olup olmadığını kontrol etmek için IsContinue metodu vardır. First metoduyla Iteration’ın başlayacağı nesye gönderen metod bulunmaktadır.
İstemci Aggregate nesnesini kullanıp, bu nesne içerisinde dolaşmak için Iterator’den yardım almaktadır. Yine Aggregate’ten türetilen bir ConcreteAggregate sınıfı, Iterator sınıfından türetilen ConcreteIterator sınıfı bulunmaktadır.
Şimdi bir örnekle buraya kadar bahsettiklerimizi daha anlaşılır bir hale getirelim.
Employee tipinde nesnelerin oluşturduğu bir nesne kümesi(List<Employee>) içerisinde Employee üyeleri arasında Itarator Patter yardımıyla dolaşarak Iterator Pattern in yapısı öğrenmeye çalışacağız.
Örnek Kodlarımız:
// Employee Sınıfı
public class Employee
{
// Fields
private int _employeeId;
private string _name;
private decimal _salary;
// Properties
public int EmployeeId
{
get { return _employeeId; }
set { _employeeId = value; }
}
public string Name
{
get { return _name; }
set { _name = value; }
}
public decimal Salary
{
get { return _salary; }
set { _salary = value; }
}
// Methods
public override string ToString()
{
return string.Format("{0}{1}{2}", EmployeeId.ToString(), Name, Salary.ToString("C2"));
}
}
// Iterator
// IEmployeeIterator arayüzü
// Nesne içerisinde yapılmasını tasarladığımız işlemler için gerekli arayüz
public interface IEmployeeIterator
{
Employee First();
Employee MoveNext();
bool IsContinue { get; }
Employee Current { get; }
}
// IEmployeeCollection arayüzü
public interface IEmployeeCollection
{
IEmployeeIterator GetIterator();
}
// ConcreteAggregate
// IEmployeeCollection arayüzünden türeyen EmployeeCollection sınıfı
public class EmployeeCollection : IEmployeeCollection
{
// Employee Listini saklamak için oluşturulan generic List<T> kolleksiyon
private List<Employee> list = new List<Employee>();
// çalışanların sayısını veren özellik
public int EmployeeCount
{
get { return list.Count; }
}
// çalışanların eklenmesi ve eklenenlerin okunması için kullanılan indexleyici
public Employee this[int index]
{
get { return list[index]; }
set { list.Add(value); }
}
// Iterator nesnesini örnekler
public IEmployeeIterator GetIterator()
{
//Iterator Nesnesi örneklenirken o andaki EmployeeCollection nesnesi referans olarak örneklenir ve böylecehangi nesneyi dolaşacağını bilecektir.
return new EmployeeIterator(this);
}
}
// ConcreteIterator
// IEmployeeIterator arayüzünden türeyen EmployeeIterator sınıfı
public class EmployeeIterator : IEmployeeIterator
{
//Iterator Nesnesi, çalışma zamanında hangi nesneyi dolaşacağını bilmesi gerekir.
private EmployeeCollection _employeeCol;
private int _currentIndex = 0;
// StepSize ile Nesne bütünü arasında kaçar kaçar dolaşacağını belirtir(birer birer, üçer üçer gibi) verilecek parametreyle belirlenir.
public int StepSize { get; set; }
public EmployeeIterator(EmployeeCollection employeeCollection)
{
_employeeCol = employeeCollection;
}
// ilk elemana gidilen metod
public Employee First()
{
_currentIndex = 0;
return _employeeCol[0];
}
// Bir sonraki metoda götüren metod
public Employee MoveNext()
{
_currentIndex += StepSize;
if (IsContinue)
{
return _employeeCol[_currentIndex];
}
else
{
return null;
}
}
// O anki elemanı döndürür
public Employee Current
{
get { return _employeeCol[_currentIndex]; }
}
//Bir sonraki employee nin olup olmadığını kontrol eder
public bool IsContinue
{
get { return _currentIndex < _employeeCol.EmployeeCount; }
}
}
class Program
{
static void Main(string[] args)
{
EmployeeCollection employees = new EmployeeCollection();
employees[0] = new Employee { EmployeeId = 1, Name = "Hasan Yalçın ", Salary = 1500M };
employees[1] = new Employee { EmployeeId = 2, Name = "Kamil Eker ", Salary = 2000M };
employees[2] = new Employee { EmployeeId = 3, Name = "Cemil Taşdöğen ", Salary = 1750M };
// Itarator Nesnesi employees adlı koleksiyonu kullanmak için oluşuturulur.
EmployeeIterator emIterator = new EmployeeIterator(employees);
// Adım sayısı belirlenir.
emIterator.StepSize = 1;
for (Employee employee = emIterator.First(); emIterator.IsContinue; employee = emIterator.MoveNext())
{
Console.WriteLine(employee.ToString());
}
}
}
Sonuç:

Faydalı olması dileğiyle.