Iterator

Lets you traverse elements of a collection without exposing its underlying representation (list, stack, tree, etc.).

classDiagram
    class Iterator {
        <<interface>>
        +getNext()
        +hasMore()
    }
    class IterableCollection {
        <<interface>>
        +createIterator()
    }
    class ConcreteCollection {
        +createIterator()
    }
    class ConcreteIterator {
        -ConcreteCollection collection
        -iterationState
        +getNext()
        +hasMore()
    }

    IterableCollection <|.. ConcreteCollection
    Iterator <|.. ConcreteIterator
    ConcreteCollection ..> ConcreteIterator

When to use

Use the Iterator pattern when your collection has a complex data structure under the hood, but you want to hide its complexity from clients. Use when you want to reduce duplication of the traversal code across your app.

Explanation

Problem

Collections are one of the most used data types in programming. Nonetheless, a collection is just a container for a group of objects.

Most collections store their elements in simple lists. However, some of them are based on stacks, trees, graphs and other complex data structures.

But how do you traverse the elements of such a collection? There should be a way to go through each element of the collection without accessing the same elements over and over.

Solution

The main idea of the Iterator pattern is to extract the traversal behavior of a collection into a separate object called an iterator.

In addition to implementing the algorithm itself, an iterator object encapsulates all of the traversal details, such as the current position and how many elements are left till the end. Because of this, several iterators can go through the same collection at the same time, independently of each other.

Real world problem

  1. Sightseeing: Visiting Rome. You can listen to a Guide (Iterator) who takes you through specific places. Or you can use a Google Maps (Iterator) for the shortest path.
  2. Social Network: Iterating over “Friends”, “Coworkers”, or “Family” profiles from the same “User” graph.
  3. Media Player: Shuffle vs Sequential playlist traversal.

Pros and Cons

Pros Cons
- Single Responsibility Principle: You can clean up the client code and the collections by extracting bulky traversal algorithms into separate classes.
- Open/Closed Principle: You can implement new types of collections and iterators and pass them to existing code without breaking anything.
- Parallel Iteration: You can iterate over the same collection in parallel because each iterator object contains its own iteration state.
- Overkill: Applying the pattern can be an overkill if your app only works with simple collections.
- Efficiency: Using an iterator may be less efficient than going through elements of some specialized collections directly.

Query

  • Composite: You can use Iterators to traverse Composite trees.
  • Factory Method: You can use Factory Method to let a collection subclass return different types of iterators.
  • Memento: You can use Memento to capture the current iteration state.

Code example

Typescript

Php