Wednesday, May 1, 2013

Iterator Design Pattern

Iterator design pattern is used to give common functionality for different collections irrespective of its structure. It encapsulates the collection and provides user common set methods to use.

To implement we need two Interfaces:
First Interface - Iterator Object
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace IteratorPattern
{
    interface IObject
    {
        IIterator CreateItrator();
    }
}

Second Interface - Iterator Methods
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace IteratorPattern
{
    public interface IIterator
    {
        void First();
        object Next();
        bool IsEnd();
        object GetAt(int iPos);
    }
}

Now need to implement these two interfaces, first we will take the IObject interface for List and Array.
IObject interface has CreateIterator method, it is basically used to create iterator class object, assign data (if required) and return it.

Implementation of List object
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace IteratorPattern
{
    public class ListClass : IObject
    {
        private List<string> lItem = new List<string>();
        public ListClass()
        {
            lItem.Add("Record 1");
            lItem.Add("Record 2");
            lItem.Add("Record 3");
            lItem.Add("Record 4");
        }

        public IIterator CreateItrator()
        {
            return new ListIterator(lItem);
        }
    }
}

Implementation of String Array object
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace IteratorPattern
{
    public class ArrayClass : IObject
    {
        private string[] saData;
        public ArrayClass()
        {
            saData = new string[] { "Field 1", "Field 2", "Field 3" };
        }

        public IIterator CreateItrator()
        {
            return new ArrayIterator(saData);
        }
    }
}

Now need to implement Iterator methods for each collection using IIterator interface.
You must be wondering why we need interface to implement it? To make user oblivious of different types of iterator and give common functionality. You will understand in the implementation at the end.

Implementation of List iterator
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace IteratorPattern
{
    public class ListIterator : IIterator
    {
        List<string> lList;
        int iPos;
        public ListIterator(List<string> lList)
        {
            this.lList = lList;
        }
        public void First()
        {
            iPos = 0;
        }

        public object Next()
        {
            return lList[iPos++];
        }

        public bool IsEnd()
        {
            return iPos >= lList.Count;
        }

        public object GetAt(int iPos)
        {
            return lList[iPos];
        }
    }
}

Implementation of Array iterator
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace IteratorPattern
{
    public class ArrayIterator : IIterator
    {
        private string[] sArray;
        int iPos;
        public ArrayIterator(string[] sArray)
        {
            this.sArray = sArray;
        }
        public void First()
        {
            iPos = 0;
        }

        public object Next()
        {
            return sArray[iPos++];
        }

        public bool IsEnd()
        {
            return iPos >= sArray.Length;
        }

        public object GetAt(int iPos)
        {
            return sArray[iPos];
        }
    }
}

Sample implementation which displays GetAt method for different iterators using console application.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace IteratorPattern
{
    class Program
    {
        static void Main(string[] args)
        {
            IObject obj = new ListClass();
            IIterator IIR = obj.CreateItrator();
            string sdata = (string)IIR.GetAt(2);
            Console.WriteLine(sdata);

            IObject obj1 = new ArrayClass();
            IIterator IIR1 = obj1.CreateItrator();
            string sdata1 = (string)IIR1.GetAt(2);
            Console.WriteLine(sdata1);

            Console.ReadKey();
        }
    }
}

Output 
Record 3                                                     
Field 3                                                      

No comments:

Post a Comment