Interpreter design pattern is used to access elements
of collection sequentially. Iterator Pattern falls under behavioral pattern of
GOF (Gang of Four) patterns.
When to use –
Iterator pattern provides a way to access elements of
collection sequentially without exposing its representation. The client code
should not be concerned about the actual implementation of traversing the
elements of collection. The iterator pattern encapsulates such implementation
and provides common way to traverse different types of collection.
Major components of Iterator pattern –
Client – This class creates an instance of collection
object (ConcreteAggreate) and iterator object to perform next operation on
collection to retrieve next items until all items are retrieved.
Iterator – The Iterator interface defines all the
methods to traverse the collection.
ConcreteIterator – This class implements the Iterator
interface and provides actual implementation of how the elements are traverse
in collection.
Aggregate – This is an abstract class. This class
defines method to create an Iterator.
ConcreteAggregate – This class will be derived from
abstract class Aggregate and implements and creates an iterator object.
Let’s have a look on below example of Iterator pattern.
Code –
class Program
{
//Client
static void Main(string[] args)
{
//Create myObject collection and items to it.
MyObjectCollection aggr = new MyObjectCollection();
aggr.Add(10);
aggr.Add(-20);
aggr.Add("Test");
aggr.Add(33);
aggr.Add("Iterator");
aggr.Add(52.6);
//Get Iterator and iterator all items
Iterator itor = aggr.GetIterator();
while (!itor.IsDone())
{
Console.WriteLine(itor.CurrentItem().ToString());
itor.Next();
}
Console.ReadLine();
}
}
//Iterator
public interface Iterator
{
object First();
object Next();
object CurrentItem();
bool IsDone();
}
//ConcreteIterator
public class MyIterator : Iterator
{
private MyObjectCollection aggregate;
int index;
public MyIterator(MyObjectCollection aggr)
{
this.aggregate = aggr;
index = 0;
}
public object CurrentItem()
{
return aggregate[index];
}
public object First()
{
return aggregate[0];
}
public bool IsDone()
{
return index >= aggregate.Count ;
}
public object Next()
{
object retVal = null;
if (index < aggregate.Count)
retVal
= aggregate[index++];
return retVal;
}
}
//Aggregate
public abstract class Aggregate
{
public abstract Iterator GetIterator();
}
//ConcreteAggregate
public class MyObjectCollection : Aggregate
{
private ArrayList myList = new ArrayList();
public override Iterator GetIterator()
{
return new MyIterator(this);
}
public object this[int index]
{
get { return myList[index]; }
}
public int Count
{
get { return myList.Count; }
}
public void Add (object obj)
{
myList.Add(obj);
}
}
Output –
As you can see in this example, I created an instance of MyObjectCollection
class and added few data items to it. I used ArrayList to add any object to the
collection. You can use any type as per your requirement. You can
also use generic type here. I get instance of iterator from MyObjectCollection
instance and I’m iterating all the items of my collection using iterator instance. I’m
using Iterator.Next() method to iterate to next item and Iterator.CurrentItem()
to get current item of collection.
The Iterator patterns are available inbuilt with Microsoft .Net.
It provides two interfaces IEnumerable
and IEnumerator. You can make your Iterator collection implementing IEnumerable
interface. Almost all majorly used collections available in .Net implements
IEnumerable interface. The few examples of inbuilt collections are
List<T>, Dictionary<T>, ArrayList, SortedList etc. See below definition
of both the interfaces.
public interface IEnumerable
{
IEnumerator
GetEnumerator();
}
public interface IEnumerator
{
object Current { get; }
bool MoveNext();
void Reset();
}
Let’s have a look on below example of custom collection implementing
IEnumerable interface.
class Program
{
static void Main(string[] args)
{
MyCollection coll = new MyCollection();
foreach(var item in coll)
Console.WriteLine(item.ToString());
Console.ReadLine();
}
}
public class MyCollection : IEnumerable
{
List<int> myList = new List<int>() { 2, 5, 3, 6, 4, 9 };
public IEnumerator GetEnumerator()
{
foreach (var item in myList)
yield return item;
}
}
Output –
As per above code, IEnumerable provides GetEnumerator method
which will return IEnumerator list. This list iterated through foreach loop in
main class. The yield return keyword can be used to provide a value to
the enumerator object.
You can download full code of Iterator Design Pattern from here. You can download code for Iterator Pattern implementing IEnumerable interface from here
I hope this article helps you to know more about Iterator
Design Pattern. Please leave your feedback in comments section below.
References –
See Also –
Creational Patterns
|
Structural Patterns
|
Behavioral Patterns
|
|
||
|
|
|
|
|
|
|
|
|
|
|