Table of Contents
What is the Iterator Pattern?
The definition of the Iterator Pattern from both Design Patterns: Elements of Reusable Object-Oriented Software and Head First Design Patterns: A Brain-Friendly Guide is
The Iterator Pattern provides a way to access the elements of an aggregate object sequentially without exposing its underlying representation
Iterator Pattern Class Diagram Explained
So just above this the generic class diagram of the Iterator Pattern. Basically, the ConcreteAggregate class implements the CreateIterator() method of the Aggregate interface that creates the ConcreteIterator and returns it as an Iterator interface to a Client for use. Note, the Client is not aware of the concrete objects.
Iterator Pattern Example
The diagram above is a class diagram of an example I designed as an example of the Iterator Pattern. As the Aggregate interface, I have defined a template class List. I have designed two implementations of the List interface. I decided to have an implementation that used a std::vector to contain the Items and called it StdVectorList. For the second, I just used an array of Items and called it ArrayList. The Iterator Pattern calls for each ConcreteAggregate have their own custom iterator objects, so we have StdVectorListIterator and ArrayListIterator, respectively. Each of these iterators, the pattern requires each to implements the same Iterator interface.
Example written in C++
So we have our design finished. Let’s take a look and see what our implementation will look like.
List.h
StdVectorList.h
ArrayList.h
Iterator.h
StdVectorListIterator.h
ArrayListIterator.h
So I am a big New York Mets baseball fan so I thought it would be fun make use of the iterator pattern by implementing the lineup “card” for a game between the New York Mets and division rival Washington Nationals. So I created an BaseballPlayer object and give it some attributes, like name, position and swing type (Left, Right, Switch). I use this object as my template class type.
BaseballPlayer.h
BaseballPlayer.cpp
So I have assigned the nice StdVectorList to contain the Mets’ lineup and the not so nice ArrayList (had to dig on the rival team a little bit!) for the Nationals. Each are created with their own methods, MakeNewYorkMetsLineup() and MakeWashingtonNationalsLineup(). The PrintLineup() method acts as my Client as all it knows about is the Iterator interface. It uses the Iterator for each team to iterate through their lineups and print them out.
IteratorTest.cpp
Here’s is the output of the program.
New York Mets Lineup
1. CF Curtis Granderson L
2. SS Asdrubal Cabrera S
3. LF Yoenis Cespedes R
4. RF Jay Bruce L
5. 2B Neil Walker S
6. 1B Lucas Duda L
7. C Travis d'Arnaud R
8. SS Jose Reyes S
9. P Noah Syndergaard L
Washington Nationals Lineup
1. CF Adam Eaton L
2. SS Wilmer Difo R
3. 2B Daniel Murphy L
4. RF Bryce Harper L
5. 1B Ryan Zimmerman L
6. 3B Anthony Rendon R
7. C Matt Wieters R
8. CF Michael Taylor R
9. P Stephen Strasburg S
All the code for this post can be found here.
Benefits of the Iterator Pattern
There are a few benefits to using the Iterator pattern. First, the traversal of the aggregate can vary. Meaning the pattern is flexible in that the traversal algorithm can easily change by swapping in a different implementation of the Iterator. Second, the pattern supports the Single Responsibility Design principle. Meaning, this allows the aggregate class to have one responsibility and not have to have additional operations to deal with the traversal of its elements. Lastly, the Iterator Pattern allows for multiple traversals of the aggregate at any given time.
Recommended Resources
Here are some resources I recommend for more information on the Iterator Pattern
Head First Design Patterns: A Brain-Friendly Guide
Design Patterns: Elements of Reusable Object-Oriented Software
In Closing
There you have it. If you followed along, I hope you now have a better understanding of the Iterator Pattern. Please feel free to leave comments and feedback. Much appreciated!