The Problem
Collections are often easy to traverse when they are just slices, but traversal logic gets messy when you need custom ordering, filtering, or resumable state. Embedding those rules into every caller duplicates behavior and ties clients to the collection internals.
The Solution
Iterator moves traversal state into a dedicated object. In Go, a simple iterator interface with Next or HasNext plus a concrete iterator struct is usually enough. The aggregate exposes a factory method for creating the iterator, and callers consume the collection through that traversal contract.
Structure
- Iterator interface:
ProductIteratorcontrols traversal. - Concrete iterator:
SliceIteratortracks position over the catalog. - Aggregate:
Catalogcreates iterators for its internal collection. - Client: Consumes items through the iterator without reaching into aggregate internals.
Implementation
This example iterates over a product catalog using an explicit iterator object. The caller sees a stable traversal contract even though the aggregate owns the underlying slice and traversal state.
package main
type Product struct {
SKU string
InStock bool
}
type ProductIterator interface {
HasNext() bool
Next() Product
} Best Practices
- Keep iterator interfaces tiny so callers only depend on traversal behavior.
- Use iterators when traversal rules matter; plain
for rangestays clearer for simple slices. - Let the aggregate create iterators so collection internals stay encapsulated.
- Document whether iterators are snapshot-based or observe live collection changes.
- Avoid forcing iterator objects into code that naturally reads as ordinary range loops.
When to Use
- Traversal needs custom state, ordering, or filtering.
- You want to hide the collection representation from callers.
- The same collection may need several traversal strategies.
When NOT to Use
- A plain slice and
for rangeloop are already obvious. - The iterator abstraction would be more ceremony than benefit.
- Traversal is trivial and there is no internal representation worth hiding.