The Iterator Design Pattern

The Iterator pattern provides a way to access the elements of an aggregate object without exposing its underlying structure.

Use the Iterator pattern when you want to access the elements of an aggregate object sequentially without exposing its underlying representation.

  • TypeBehavioral
  • Time ComplexityO(n) Linear Time – The time taken grows linearly with the size of the input. Examples include simple search algorithms.
  • Efficiency6
  • Learning Effort

    • Average4
    • Conceptual4
    • Debug and Maintain4
    • Implementation5
    • Prerequisites3
    • Versatility6

Things you should know before you start

  • Encapsulation Understanding of encapsulation, as the Iterator pattern encapsulates the traversal logic.
  • Polymorphism Understanding of polymorphism, as different types of collections can use different types of iterators.

Minimal Example

Implementing a bookshelf where books can be accessed one at a time without knowing the underlying data structure.

class BookIterator implements Iterator {
  hasNext(): boolean { /* ... */ }
  next(): Book { /* ... */ }
}
const bookIterator = new BookIterator(bookShelf);
while (bookIterator.hasNext()) {
  const book = bookIterator.next();
  console.log(book.title);
}

What’s happening in thie example

In this example, the `BookIterator` is a ConcreteIterator that allows for sequential access to books in a bookshelf. The `clientCode` shows how to use the iterator to access each book one at a time.

How the Iterator Works

The Iterator pattern allows for traversal of elements in a collection without exposing the internal details of the collection.

This pattern is particularly useful for different kinds of collections such as lists, trees, and graphs.

Entities in the Iterator Design Pattern

  • IteratorThe Iterator interface defines methods for accessing elements in a collection.

    • Iterator has a one-to-many implements relationship with ConcreteIterator

What to watch out for when using or considering this design pattern.

Avoid using the Iterator pattern if your collection is simple and does not require complex traversal logic, or if performance is a critical concern, as iterators can add overhead.

Design patterns often confused with the Iterator Design Pattern

The following design patterns are often confused with the Iterator
for various resons.

If you’re exploring solutions, have a look through this list and see if
one of these might be a better fit for your problem.

  • Composite – The Composite pattern composes objects into tree structures to represent part-whole hierarchies.

    The Composite pattern is similar to the Iterator in the following ways.

    • Both patterns deal with collections of objects.
    • Both patterns can be used to traverse hierarchical structures.
  • Here are some notable differences with the Iterator pattern.

    • Iterator is focused on sequential traversal, while Composite is focused on handling part-whole hierarchies.
    • Iterator provides a standard interface for traversal, while Composite does not necessarily provide this.
  • Observer – The Observer pattern defines a one-to-many dependency between objects so that when one object changes state, all its dependents are notified.

    The Observer pattern is similar to the Iterator in the following ways.

    • Both are behavioral design patterns.
    • Both deal with object collections.
  • Here are some notable differences with the Iterator pattern.

    • Iterator is used for traversing collections, while Observer is used for event handling and notification.
    • Iterator allows for manual control of traversal, while Observer automatically notifies dependents.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top