Card 02/ 09
Iterator Pattern Structure: The Class Diagram
An Aggregate creates an Iterator, and the Iterator keeps the position.
Iterator has four participants: an aggregate interface and its concrete class, and an iterator interface and its concrete class. This card reads their roles off the Gang of Four's class diagram, names each one in Python, Java and TypeScript, and explains why the position is kept in the iterator rather than in the collection.
| Participant | Role | Python | Java | TypeScript |
|---|---|---|---|---|
| Aggregate | Declares the method that creates an iterator | __iter__ | Iterable<T> | Iterable<T> |
| ConcreteAggregate | Holds the elements and returns an iterator over them | A class with __iter__ | A class implementing Iterable | A class with [Symbol.iterator]() |
| Iterator | Declares how to get the next element and how to tell the end | __next__, raising StopIteration at the end | hasNext() and next() | next(), returning { done, value } |
| ConcreteIterator | Keeps the position and returns elements one at a time | A class with __next__ | A class implementing Iterator | An object with next() |
The Gang of Four's diagram names the iterator's methods first, next, isDone and currentItem; the three languages fold them into one or two methods, and the diagram above uses those.
The position lives in the iterator, not in the aggregate, because two loops over the same collection must not share it. A nested loop that compares every song with every other song walks the playlist twice at once, and each walk needs its own place. Because each call to the aggregate's creating method returns a fresh iterator, each walk has its own position.
The creating method is itself a factory method: the aggregate decides which concrete iterator to build, and the caller sees only the interface.
← → move through sections and cards