Iterátor programtervezési minta

Az objektumorientált programozásban az iterátor olyan tervezési minta, melyet arra használunk, hogy bejárjunk egy containert és elérjük annak elemeit. Az Iterátor minta szétválogatja a container algoritmusait; egyes esetekben viszont ezek az algoritmusok container-specifikusak és így nem nem lehet őket függetleníteni.

Például, egy képzeletbeli SearchForElement algoritmust általában végrehajthatunk egy meghatározott típusú iterátorral, ahelyett, hogy container-specifikus algoritmusként implementálnánk. ezáltal a SearchForElement bármely container által használható, mely támogatja a kívánt típusú iterátort.

Definíció

[szerkesztés]

Az Iterátor Aggregator minta lényege, hogy segítségével szekvenciálisan érhetjük el egy aggregált objektum elemeit, a mögöttes megvalósítás megismerése nélkül.

Nyelv specifikus végrehajtás Néhány nyelv standardizálja a szintaxist. A C++ és a Python figyelemre méltó példa lehet.

A C++ a pointerek szemantikájával valósítja meg az Iterátorokat. A C++-ban egy osztály megtölthetünk pointer műveletekkel, ezáltal az Iterátort implementálhatjuk többé-kevésbé pointer mintára, mely rendelkezik, feloldással, növeléssel és csökkentéssel. Ennek előnye, hogy a C++ algoritmusokat, mint például a std::sort azonnal alkalmazhatóak korábbi memória pufferekre és hogy ehhez nem kell új szintaxist megtanulni. Ugyanakkor szükség van egy vég-Iterátorra az egyenlőség teszteléséhez, ahelyett hogy az Iterátor felismerné, hogy elért a művelet végére. Úgy mondjuk, hogy a C++ nyelvben az Iterátor modellezi az Iterátor koncepcióját.

A Java-ban van Iterátor interfész. A Java 5 óta az olyan objektumok, melyek implementálják az Iterable interfészt, mely egyetlen metódus segítségével visszaad egy Iterátort, bejárhatók egy továbbfejlesztett for loop szintaxis segítségével.[1] A Java collection frameworkben található Collection interfész kiterjed az Iterátorra is.

Python

[szerkesztés]

A Python a nyelv részeként előre meghatározza az Iterátorok szintaxisát, így a nyelv kulcsszavai, mint például a for, működhetnek a Python által használt szekvenciákkal. A szekvenciának van egy __iter__() metódusa, mely visszaad egy Iterátor objektumot. Az "Iterátor protokoll"-hoz tartozik a next(), mely a következő elemet adja vissza, vagy egy stopIteration kivétel, amikor elért a szekvencia végére. Az Iterátorok rendelkeznek továbbá egy __iter__() metódussal, melynek segítségével önmagukat adják vissza, hogy újra iterálhatóak legyenek, például a for loop használatával. A generátorok a 2.2. óta elérhetőek.

A Python 3-ban a next()-et átnevezték __next__()-re.[2]

A PHP az Iterátor Interfészen keresztül alkalmazza iterátor mintát, ami a standard csomag része.[3] Azok az objektumok, melyek implementálják ezt az interfészt bejárhatók a foreach nyelvi konstrukcióval.

Példa mintákra a PHP-ben

interface IIterator {
    /*
     * @param: void
     * @return:Boolean
     */
    public function hasNext();
 
    /*
     * @param: void
     * @return: String
     */
    public function next();
}
 
interface IContainer {
    /*
     * @param: void
     * @return: IInterator
     */
    public function createIterator();
}
 
class BooksCollection implements IContainer {
    private $a_titles = array();
 
    /*
     * @param: void
     * @return: IIterator
     */
    public function createIterator()
    {
        return new BookIterator($this);
    }
 
    /*
     * @param: string
     * @return: void
     */
    public function setTitle($string)
    {
        $this->a_titles[] = $string;
    }
 
    /*
     * @param: void
     * @return: Array
     */
    public function getTitles(){
        return $this->a_titles;
    }
}
 
class BookIterator implements IIterator {
    private $i_position = 0;
    private $booksCollection;
 
    function __construct(BooksCollection $booksCollection)
    {
        $this->booksCollection = $booksCollection;
    }
 
    /*
     * @param: void
     * @return: Boolean
     */
    public function hasNext()
    {
        if ($this->i_position < count($this->booksCollection->getTitles())) {
            return true;
        }
        return false;
    }
 
    /*
     * @param: void
     * @return: String
     */
    public function next()
    {
        $m_titles = $this->booksCollection->getTitles();
 
        if ($this->hasNext()) {
            return $m_titles[$this->i_position++];
        } else {
            return null;
        }
    }
}
 
class Tester {
    static function Main() {
        $booksCollection = new BooksCollection();
 
        $booksCollection->setTitle("Design Patterns");
        $booksCollection->setTitle("1");
        $booksCollection->setTitle("2");
        $booksCollection->setTitle("3");
 
        $iterator = $booksCollection->createIterator();
        while ($iterator->hasNext()) {
            echo $iterator->next() . '<br />';
        }
    }
}
 
Tester::Main();

Kapcsolódó szócikkek

[szerkesztés]

Jegyzetek

[szerkesztés]
  1. An enhanced for loop for the Java™ Programming Language. (Hozzáférés: 2013. június 25.)
  2. Python v2.7.1 documentation: The Python Standard Library: 5. Built-in Types. (Hozzáférés: 2011. május 2.)
  3. PHP: Iterator. (Hozzáférés: 2013. június 23.)

További idegen nyelvű irodalom

[szerkesztés]
Az angol Wikikönyvekben
további információk találhatók

Fordítás

[szerkesztés]

Ez a szócikk részben vagy egészben az Iterator pattern című angol Wikipédia-szócikk ezen változatának fordításán alapul. Az eredeti cikk szerkesztőit annak laptörténete sorolja fel. Ez a jelzés csupán a megfogalmazás eredetét és a szerzői jogokat jelzi, nem szolgál a cikkben szereplő információk forrásmegjelöléseként.