This is part of a series of posts demonstrating software design patterns using C# and .NET. The patterns are taken from the book Design Patterns by the Gang of Four. Here's the series index page.

What Is This Pattern?

The Iterator pattern provides a way to access objects in an underlying representation without exposing access to the representation itself.

The idea is that we'll have a class (the "Iterator") which contains a reference to a corresponding aggregate object, and that Iterator can traverse over its aggregate to retrieve individual objects.

The Rundown

  • Type: Behavioral
  • Useful? 5/5 (Extremely)
  • Good For: Extracting objects from a collection without exposing the collection itself.
  • Example Code: On GitHub

The Participants

  • The Iterator defines an interface for accessing an Aggregate object and traversing elements within that Aggregate.
  • The ConcreteIterator implements the Iterator interface and keeps track of its current position within the Aggregate.
  • The Aggregate defines an interface for creating an Iterator object.
  • The ConcreteAggregate implements the Iterator creation interface and returns a ConcreteIterator for that ConcreteAggregate.

A Delicious Example

To demo how we might use the Iterator design pattern, let's talk about my favorite sugary snack: jelly beans. So far as I am concerned, these little nuggets of sugar and flavor are the best thing since sliced bread.

A bunch of different kinds of jelly beans Image is JellyBellyBeans from Wikimedia, used under license.

We want to build a collection for a group of jelly beans and have that collection create an iterator for itself. To do this, let's first define a class to represent a single jelly bean.

/// <summary>
/// Our collection item.  Mostly because I'm a sucker for jelly beans.
/// </summary>
class JellyBean  
{
    private string _flavor;

    // Constructor
    public JellyBean(string flavor)
    {
        this._flavor = flavor;
    }


    public string Flavor
    {
        get { return _flavor; }
    }
}

Next we need both our Aggregate and ConcreteAggregate participants, which represent a collection of jelly beans.

/// <summary>
/// The aggregate interface
/// </summary>
interface ICandyCollection  
{
    IJellyBeanIterator CreateIterator();
}

/// <summary>
/// The ConcreteAggregate class
/// </summary>
class JellyBeanCollection : ICandyCollection  
{
    private ArrayList _items = new ArrayList();

    public JellyBeanIterator CreateIterator()
    {
        return new JellyBeanIterator(this);
    }

    // Gets jelly bean count
    public int Count
    {
        get { return _items.Count; }
    }

    // Indexer
    public object this[int index]
    {
        get { return _items[index]; }
        set { _items.Add(value); }
    }
}

Now we can define our Iterator and ConcreteIterator participants.

/// <summary>
/// The 'Iterator' interface
/// </summary>
interface IJellyBeanIterator  
{
    JellyBean First();
    JellyBean Next();
    bool IsDone { get; }
    JellyBean CurrentBean { get; }
}

/// <summary>
/// The 'ConcreteIterator' class
/// </summary>
class JellyBeanIterator : IJellyBeanIterator  
{
    private JellyBeanCollection _jellyBeans;
    private int _current = 0;
    private int _step = 1;

    // Constructor
    public JellyBeanIterator(JellyBeanCollection beans)
    {
        this._jellyBeans = beans;
    }

    // Gets first jelly bean
    public JellyBean First()
    {
        _current = 0;
        return _jellyBeans[_current] as JellyBean;
    }

    // Gets next jelly bean
    public JellyBean Next()
    {
        _current += _step;
        if (!IsDone)
            return _jellyBeans[_current] as JellyBean;
        else
            return null;
    }

    // Gets current iterator candy
    public JellyBean CurrentBean
    {
        get { return _jellyBeans[_current] as JellyBean; }
    }

    // Gets whether iteration is complete
    public bool IsDone
    {
        get { return _current >= _jellyBeans.Count; }
    }
}

Notice that the ConcreteAggregate needs to implement methods by which we can manipulate objects within the collection, without exposing the collection itself. This is how it can fit with the Iterator design pattern.

Finally, in our Main(), we can create a collection of jelly beans and then iterate over them:

static void Main(string[] args)  
{
    // Build a collection of jelly beans
    JellyBeanCollection collection = new JellyBeanCollection();
    collection[0] = new JellyBean("Cherry");
    collection[1] = new JellyBean("Bubble Gum");
    collection[2] = new JellyBean("Root Beer");
    collection[3] = new JellyBean("French Vanilla");
    collection[4] = new JellyBean("Licorice");
    collection[5] = new JellyBean("Buttered Popcorn");
    collection[6] = new JellyBean("Juicy Pear");
    collection[7] = new JellyBean("Cinnamon");
    collection[8] = new JellyBean("Coconut");

    // Create iterator
    JellyBeanIterator iterator = collection.CreateIterator();

    Console.WriteLine("Gimme all the jelly beans!");

    for (JellyBean item = iterator.First();
        !iterator.IsDone; item = iterator.Next())
    {
        Console.WriteLine(item.Flavor);
    }

    Console.ReadKey();
}

Will I Ever Use This Pattern?

Absolutely. The pattern is astonishingly useful when attempting to retrieve objects from collections that you'd rather not expose to outside usage (because that's, like, the pattern's entire purpose). If you primarily work in the ASP.NET world (as I do) and you use LINQ, you are already using the Iterator pattern extensively (e.g. collection.First() or collection.Count()).

Summary

The Iterator pattern provides a manner in which we can access and manipulate objects in a collection without exposing the collection itself. This pattern is incredibly common and incredibly useful, so keep it in mind; once you know what it is, you'll start seeing it everywhere.

As always, I like to provide code with my tutorials, so the repository for this pattern is over on GitHub and contains all of the sample code used here.

Aaaaand now I need some sugar. The literal kind. Gimme all the jelly beans!

A bunch of jelly beans in two hands. Image is Jellybeans in cupped hands from Wikimedia, used under license

Now THAT'S what I'm talking about.

Happy Coding!

Get My eBook FREE!

Did you enjoy this post? This article and 21 others are also in my free eBook, "The Daily Design Pattern", which you can get just by signing up for my email list.