Tekrarlayıcı Tasarım Kalıbı (Iterator Pattern)

Eyl 08, 2013

Tekrarlayıcı tasarım kalıbı; birleşik bir nesnenin bileşenlerine, nesnenin esas ifadesinin gösterilimini açığa çıkarmadan sırayla erişebilmeyi sağlar.

Kullanıldığı Durumlar

Tekrarlayıcı tasarım kalıbı, bir listenin yapısının ve çalışma tarzının uygulamanın diğer kısımları ile olan bağlantılarını en aza indirmek için; listede yer alan nesnelerin, sırasıyla uygulamadan soyutlanması amacıyla kullanılır.

Tekrarlayıcı Tasarım Kalıbının Yapısı

Tekrarlayıcı kalıbın içinde yer alan yapılar aşağıdaki gibi sıralanır:

  • Tekrarlayıcı (Iterator): Öğelere ulaşmak ve öğeleri çaprazlamak için bir arabirim tanımlar.
  • Somut Tekrarlayıcı (Concrete Iterator): Tekrarlayıcı arayüzünü sağlar.
  • Birleşik (Aggregate): Tekrarlayıcı nesnelerin yaratılması için bir arabirim oluşturur.
  • Somut Birleşik (Concrete Aggregate): Uygun somut tekrarlayıcı aşamasına dönmek için tekrarlayıcı arabiriminin oluşturulmasını sağlar.

Bu yapısal kod; koleksiyonun esas yapısını detaylandırmaksızın, nesne koleksiyonlarını tekrarlanmasını sağlayan tekrarlayıcı tasarım kalıbı örnekle gösterilebilir.

Tekrarlayıcı tasarım kalıbı diyagramı

 

Bu yapıların anlaşılması için gerçekleştirilen C# uygulaması aşağıdaki gibidir:

 

using System;
using System.Collections;
namespace DoFactory.GangOfFour.Iterator.Structural
{
    class MainApp

    {
        static void Main()
        {
            ConcreteAggregate a = new ConcreteAggregate();
            a[0] = "Item A";
            a[1] = "Item B";
            a[2] = "Item C";
            a[3] = "Item D";
            ConcreteIterator i = new ConcreteIterator(a);
            Console.WriteLine("Iterating over collection:");
            object item = i.First();

            while (item != null)
            {
                Console.WriteLine(item);
                item = i.Next();
            }
            Console.ReadKey();
        }
    }

    abstract class Aggregate
    {
        public abstract Iterator CreateIterator();
    }
    class ConcreteAggregate : Aggregate 
    {
        private ArrayList _items = new ArrayList(); 
        public override Iterator CreateIterator()
        {
            return new ConcreteIterator(this);
        }

        public int Count
        {
            get { return _items.Count; }
        }

        public object this[int index]
        {
            get { return _items[index]; }
            set { _items.Insert(index, value); }
        }
    }

    abstract class Iterator
    {
        public abstract object First();
        public abstract object Next();
        public abstract bool IsDone();
        public abstract object CurrentItem();
    }

    class ConcreteIterator : Iterator
    {
        private ConcreteAggregate _aggregate;
        private int _current = 0;

        public ConcreteIterator(ConcreteAggregate aggregate)
        {
            this._aggregate = aggregate; 
        }

        public override object First()
        {
            return _aggregate[0];
        }

        public override object Next()
        {
            object ret = null; 
            if (_current < _aggregate.Count - 1) 
            {
                ret = _aggregate[++_current];
            }
            return ret;
        }

        public override object CurrentItem()
        {
            return _aggregate[_current];
        } 

        public override bool IsDone()
        {
            return _current >= _aggregate.Count;
        }
    }
}