Iterator Pattern

The Iterator is a behavioral design pattern that provides a way to access elements of a collection sequentially without exposing its underlying representation (e.g., array, list, tree). It decouples traversal logic from the collection, enabling multiple independent traversals and hiding internal structure.

Key Principles

Structure

Python Example: Custom List Iterator

from typing import List, Any

# Iterator Interface
class Iterator:
    def has_next(self) -> bool:
        raise NotImplementedError

    def next(self) -> Any:
        raise NotImplementedError

# Concrete Iterator
class ListIterator(Iterator):
    def __init__(self, collection: List[Any]):
        self._collection = collection
        self._index = 0

    def has_next(self) -> bool:
        return self._index < len(self._collection)

    def next(self) -> Any:
        if not self.has_next():
            raise StopIteration
        item = self._collection[self._index]
        self._index += 1
        return item

# Aggregate Interface
class IterableCollection:
    def create_iterator(self) -> Iterator:
        raise NotImplementedError

# Concrete Aggregate
class CustomList(IterableCollection):
    def __init__(self):
        self._items: List[Any] = []

    def add(self, item: Any):
        self._items.append(item)

    def create_iterator(self) -> Iterator:
        return ListIterator(self._items)

# Client Code
if __name__ == "__main__":
    my_list = CustomList()
    my_list.add("Apple")
    my_list.add("Banana")
    my_list.add("Cherry")

    iterator = my_list.create_iterator()
    while iterator.has_next():
        print(f"Item: {iterator.next()}")

    # Multiple independent iterators
    iter1 = my_list.create_iterator()
    iter2 = my_list.create_iterator()
    print(f"First from iter1: {next(iter1)}")   # Apple
    print(f"First from iter2: {next(iter2)}")   # Apple

Output:

Item: Apple
Item: Banana
Item: Cherry
First from iter1: Apple
First from iter2: Apple

When to Use Iterator

Summary: Iterator separates traversal from collection, providing a standard way to iterate over elements while keeping implementation details hidden. In Python, it's built-in via __iter__() and __next__(), but the pattern is explicit in custom structures.