# Purpose
The Iterator pattern provides a way to access the elements of an aggregate object sequentially without exposing its underlying representation.
# Problem
Need to traverse collections (arrays, lists, trees) uniformly regardless of their internal structure.
# Solution
Use an iterator object that encapsulates the traversal logic. This separates the traversal logic from the business logic.
# Structure
# Participants
- Iterator: Interface for traversal.
- ConcreteIterator: Keeps track of the current position.
- Aggregate: Interface to create an iterator.
- ConcreteAggregate: Returns the proper iterator instance.
- Client: Uses the iterator for traversal.
# When to Use It
-
To hide the internal representation of a collection.
-
To support multiple traversals of aggregate objects.
# Advantages
-
verified
Separation: Traversal logic is outside the collection.
-
verified
Uniformity: Identical access to different collections.
# Disadvantages
-
warning
Complexity: Additional layers of abstraction.
-
warning
Performance: Overhead compared to direct access.
# Example: Digital Recipe Book
Navigate recipe steps sequentially (forward/backward) without showing how they are stored.
# Java Code
interface Iterator { boolean hasNext(); Object next(); }
class RecipeIterator implements Iterator {
private String[] steps;
private int pos = 0;
public boolean hasNext() { return pos < steps.length; }
public Object next() { return steps[pos++]; }
}
class Recipe implements Aggregate {
public Iterator createIterator() { return new RecipeIterator(steps); }
}
# Mapping Participants
- RecipeIterator: ConcreteIterator.
- Recipe: ConcreteAggregate.
- CookbookApp: Client.
# Conclusions
Provides great flexibility to modify the internal data structure without impacting the client code which traverses it.
# Related Patterns
Composite
To traverse complex hierarchical structures.
Factory Method
To instantiate the appropriate iterator for an aggregate.