Jednou jsem tu psal o rozhraní Iterator, dneska bych rád navázal rozhraním IteratorAggregate. Je dalším rozhraním co dědí od Traversable, z čehož vyplývá, že objekty implementující toto rozhraní je možné procházet jako kolekci pomocí konstrukce foreach.

IteratorAggregate se používá tam, kde je vhodné oddělit implementaci iterátoru od implementace samotného objektu.

Rozhraní vypadá nadmíru jednoduše:

PHP:
interface IteratorAggregate extends Traversable{
    function getIterator();
}

Objekt implementující IteratorAggregate musí tedy pomocí metody getIterator vracet iterační objekt (implementující Iterator), který se bude starat o jeho procházení. Tím je tedy oddělena logika objektu od logiky jeho procházení.

Příklad
Máme objekt Relace, který uchovává kolekci sloupců. Sloupce chceme procházet pomocí iterátoru, avšak logiku procházení nechceme míchat do objektu relace..

PHP:
class Relation implements IteratorAggregate{

    //vrátíme iterátor
    public function getIterator(){
       
        //vytvoříme nový iterátor a předáme mu objekt Relation, který bude procházet.
        return new RelationIterator( $this );

    }

    //nějaká další logika relace

}

PHP:
class RelationIterator implements Iterator{

     private $currentColumnNum;
     private $relation

     public function __construct(Relation $relation){
          $this->relation = $relation;
          $this->currentColumnNum = 0;
     }

    /**
     * Nastavení iterátoru na začátek
     */

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

    /**
     * Vrátí aktuální sloupec relace.
     *
     * @return Relation
     */

    public function current(){
        return $this->relation->getColumn( $this->currentColumnNum );
    }

    /**
     * Vrátí číslo aktuílního sloupce.
     *
     * @return int
     */

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

    /**
     * Posun na další sloupec.
     */

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

    /**
     * Existuje sloupec s aktuálním číslem sloupce?
     *
     * @return boolean
     */

    public function valid(){
        return ( $this->currentColumnNum <$this->relation->getNumOfColumns() ) ? true : false;
    }

}