← Back to Home

Iterator Pattern

Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation.

What is it?

The Iterator pattern allows sequential traversal of a collection without revealing its internal structure. It abstracts the logic of iteration into a separate object.

Example

    interface Iterator<T> {
      hasNext(): boolean;
      next(): T;
    }
    
    interface IterableCollection<T> {
      createIterator(): Iterator<T>;
    }
    
    class NameRepository implements IterableCollection<string> {
      private names: string[] = ['Alice', 'Bob', 'Charlie', 'Diana'];
    
      createIterator(): Iterator<string> {
        let index = 0;
        const names = this.names;
    
        return {
          hasNext: () => index < names.length,
          next: () => names[index++],
        };
      }
    }
    
    // Usage
    const nameRepo = new NameRepository();
    const iterator = nameRepo.createIterator();
    
    while (iterator.hasNext()) {
      console.log(iterator.next());
    }

    Common Uses

    • Traversing custom data structures
    • Abstracting away iteration logic
    • Supporting multiple iteration strategies

    When to Use

    • To iterate without exposing internal structure
    • To have multiple iterators over the same collection

    Caution

    • Overhead for small/simple collections
    • Not ideal for performance-critical tight loops