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

Rows of candy dispensers at a candy store.
Gimme some sugar! Photo by Sneha Chekuri / Unsplash

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

NOTE: This post is part of a series demonstrating software design patterns using C# and .NET. The patterns are taken from the book Design Patterns by the Gang of Four. Check out the other posts in this series!

The Rundown

  • Type: Behavioral
  • Useful? 5/5 (Extremely)
  • Good For: Extracting objects from a collection without exposing the collection itself.
  • Example Code: On GitHub
exceptionnotfound/DesignPatterns
Repository for all of my Daily Design Pattern posts. - exceptionnotfound/DesignPatterns
Project for this post: Iterator

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. As far as I am concerned, these little nuggets of sugar and flavor are the best thing since sliced bread.

A bunch of different flavors 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 JellyBean 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 an Aggregate participant, which we'll call ICandyCollection, and our ConcreteAggregate participant, which we'll call JellyBeanCollection. These classes 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() method, we will 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.

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!