Design Patterns Series 13 - Iterator Pattern

This post and the next will be about two allied patterns: the Iterator Pattern and the Composite Pattern.

The Iterator Pattern:

The Iterator Pattern gives you a way of accessing the elements inside an object without having to know the internal details of that object. When you dealing with a collection of objects, The Iterator Pattern is the ideal solution.

You can use the Iterator Pattern to "Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation." In other words, iterators are designed to let you handle many different kinds of collections by accessing their members in standard, accepted way, without having to know the internal details of those collections.

The Iterator Pattern is especially important when the collection you are creating is made up internally of separate subcollections, as when you have mixed hashes with array lists, for example.

The design insight here is one of what’s called single responsibility — a class should have only one thing to do. The thinking is that the collection maintains the collection; the iterator provides access to the elements of the collection. Separating responsibilities between classes is useful when a class has to change — if there’s too much going on in a single class, it’s going to be too hard to rewrite. When change has to happen, a single class should have only one reason to change.

What you need to iterate over any collection items are Next() to get the next item in the collection, HasNext() that returns true if the are additional item in the collection, and Remove() to remove an item from the collection. Of course your iterator can contain others action but these three actions is the basic actions for any iterator.

If you are working for a tourism company and you have a list of hotels, each hotel has a list of room types(single,double,..etc) and you want to iterate over the hotels to display the room types of each hotel.

Hotel Class
public class Hotel
{
    private Int32 count = 0;

    public Hotel(String name)
    {
        Name = name;
    }

    public String Name { get; set; }
    public RoomType[] RoomTypes = new RoomType[10];

    public void AddRoomType(String type)
    {
        RoomType rtype = new RoomType(type, Name);
        RoomTypes[count++] = rtype;
    }
    public IMyIterator Iterator()
    {
        return new RoomTypeIterator(RoomTypes);
    }
}
Hotel class contains an array of RoomType which will be populated by AddRoomType() method, Iterator() method that will return the iterator object to iterate over RoomTypes array, and a private field, count, that keep track the number of items in the RoomTypes array. That means the Hotel object is the collection and the RoomType objects are the elements in the collection.

RoomType Class
public class RoomType
{
    public RoomType(String type,String hotel)
    {
        Type = type;
        Hotel = hotel;
    }

    public String Type { get; set; }
    public String Hotel { get; set; }

    public void Print()
    {
        Console.WriteLine("Type : {0} Hotel : {1}", Type, Hotel);
    }
}
Now is the time of creating the Iterator itself. First we will create an IMyIterator interface with the three basic methods, Next(), HasNext(), and Remove().

IMyIterator interface
public interface IMyIterator
{
    Object Next();
    Boolean HasNext();
    void Remove(Object item);
}
Then we will create our iterator class, RoomTypeIterator, that implements the IMyIterator interface. Its constructor will accepts the RoomType array and store it. Also this class should keep the index of the next item, so it have a private field stores the index of the next item. Every time we call the Next() method, this field will be incremented.

RoomTypeIterator Class
public class RoomTypeIterator : IMyIterator
{
    private RoomType[] RoomTypes { get; set; }
    private Int32 index = 0;

    public RoomTypeIterator(RoomType[] roomTypes)
    {
        RoomTypes = roomTypes;
    }

    public object Next()
    {
        return RoomTypes[index++];
    }

    public bool HasNext()
    {
        if(index < RoomTypes.Length && RoomTypes[index]!=null)
        {
            return true;
        }
        return false;
    }
    public void Remove(Object item)
    {
        // remove an item from the RoomTypes array.
    }
}
That is all, we have created our Iterator, now we will iterate over the items of RoomTypes array. First we will create Hotel object and adding many room types to it, Then we will get the iterator object and iterate over them to call Print() method of each room type.
Hotel hotel = new Hotel("Hilton");

hotel.AddRoomType("Double");
hotel.AddRoomType("Single");
hotel.AddRoomType("Suite");

IMyIterator iterator = hotel.Iterator();
RoomType rtype;
while(iterator.HasNext())
{
    rtype = (RoomType)iterator.Next();
    rtype.Print();
}
This will print out
Type : Double Hotel : Hilton
Type : Single Hotel : Hilton
Type : Suite Hotel : Hilton

you can download the full source code here

Comments

Popular posts from this blog

Android : How to change progress bar color at runtime programmatically?

How to fire RowCommand event of nested GridView?

ASP.Net MVC : Conditional Validation using ValidationAttribute