OOD Fundamentals
OOP Foundations
SOLID Principles
Creational Patterns
Structural Patterns
Classic OOD Problems: Part 1
Classic OOD Problems: Part 2
Iterator and Template Method
Imagine you have a list of products, a binary tree of file system entries, and a graph of social connections. Each stores data differently: contiguous array, linked nodes, adjacency lists. But the code that processes each collection wants the same thing: give me the next element, and tell me when you are done. The Iterator pattern solves this by providing a uniform interface, hasNext() and next(), that works identically regardless of the underlying data structure.

Why Iterator Matters
Without iterators, client code must know the internal structure of every collection it processes. Traversing an array requires an index variable and a length check. Traversing a linked list requires following node pointers. Traversing a tree requires a stack or recursion. This means the code that uses the collection is tightly coupled to how the collection stores data: change the storage, break the client.
The Iterator pattern decouples traversal from storage. The collection creates an iterator object that knows how to walk through its elements. The client talks only to the iterator interface. If you swap the collection from an array to a tree, the client code does not change at all.
The Iterator Interface
Every iterator implements two core methods:
The collection itself implements a factory method that creates the appropriate iterator:
This separation means the collection owns its traversal logic but exposes it through a standard contract. An ArrayList creates an ArrayIterator that walks indices 0 to N-1. A LinkedList creates a LinkedListIterator that follows node pointers. A BinaryTree creates a TreeIterator that uses a stack for depth-first traversal. The client code is identical for all three.
The real power of Iterator is not convenience: it is that you can change a collection's internal structure without touching any code that reads from it. This is the Open/Closed Principle in action: the collection is open for extension (new storage formats) but closed for modification (client code stays unchanged).
Internal vs External Iterators
There are two flavors. An external iterator gives the client control: the client calls next() in a loop and decides when to stop, skip, or break. This is what most people think of as an iterator.
An internal iterator gives the collection control: you pass a function, and the collection applies it to every element. The forEach, map, and filter methods in modern languages are internal iterators.
External iterators are more flexible: you can iterate two collections in lockstep, break early based on complex conditions, or interleave iterations. Internal iterators are simpler: less boilerplate, less chance of off-by-one errors, and the collection can optimize traversal internally (parallel execution, lazy evaluation).