The Iterator pattern is a behavioral design pattern that allows sequential access to elements of a collection without exposing the underlying representation of the collection. It provides a way to access the elements of an aggregate object (like a collection) sequentially without needing to know the details of how the collection is implemented.

Key Characteristics:

  • Sequential Access: Provides a way to access elements in a collection one at a time.
  • Encapsulation: Encapsulates the internal representation of the collection.
  • Multiple Iterators: Allows multiple iterators to traverse the same collection concurrently.

How It Works:

  • Iterator Interface: Defines methods for traversing the collection, such as next(), current(), key(), and valid().
  • Concrete Iterator: Implements the Iterator interface and maintains the current position in the collection.
  • Aggregate Interface: Defines a method for creating an iterator.
  • Concrete Aggregate: Implements the Aggregate interface and returns an instance of the Concrete Iterator.

Example in PHP:

  // Iterator Interface
interface Iterator {
    public function next();
    public function current();
    public function key();
    public function valid();
    public function rewind();
}

// Concrete Iterator
class ConcreteIterator implements Iterator {
    private $collection;
    private $position = 0;

    public function __construct(array $collection) {
        $this->collection = $collection;
    }

    public function next() {
        $this->position++;
    }

    public function current() {
        return $this->collection[$this->position];
    }

    public function key() {
        return $this->position;
    }

    public function valid() {
        return isset($this->collection[$this->position]);
    }

    public function rewind() {
        $this->position = 0;
    }
}

// Aggregate Interface
interface Aggregate {
    public function createIterator();
}

// Concrete Aggregate
class ConcreteAggregate implements Aggregate {
    private $items = [];

    public function __construct(array $items) {
        $this->items = $items;
    }

    public function createIterator() {
        return new ConcreteIterator($this->items);
    }
}

// Client Code
$aggregate = new ConcreteAggregate(["Item1", "Item2", "Item3"]);
$iterator = $aggregate->createIterator();

foreach ($iterator as $item) {
    echo $item . "\n";
}
  

Explanation:

  1. Iterator Interface: Defines methods such as next(), current(), key(), valid(), and rewind() to traverse the collection.
  2. Concrete Iterator: ConcreteIterator implements the Iterator interface and maintains the current position in the collection. It provides the actual logic for traversing the collection.
  3. Aggregate Interface: Defines the createIterator() method to create an iterator.
  4. Concrete Aggregate: ConcreteAggregate implements the Aggregate interface and provides an instance of ConcreteIterator to traverse its items.

Benefits:

  • Encapsulation: Hides the internal representation of the collection and provides a consistent way to access elements.
  • Flexibility: Allows multiple iterators to traverse the same collection independently.
  • Ease of Use: Simplifies the traversal of complex data structures.

Use Cases:

  • Collections: For iterating over elements in collections like arrays, lists, or custom data structures.
  • Data Structures: When implementing custom data structures and providing a way to traverse them.
  • Complex Data Handling: For accessing complex or nested data structures in a standardized way.

The Iterator pattern is valuable for providing a standard way to access elements in a collection, encapsulating the internal details of the collection, and allowing flexible and consistent traversal of complex data structures.