všetky vzory

Iterator

Prechádza prvky kolekcie bez toho, aby odhalil jej vnútornú stavbu.

class ListIterator {  constructor(items) {    this.items = items;    this.position = 0;  }   hasNext() {    return this.position < this.items.length;  }   next() {    const item = this.items[this.position];    this.position += 1;    return item;  }} class ItemList {  #items = [];   add(item) {    this.#items.push(item);  }   iterator() {    return new ListIterator(this.#items);  }} const it = list.iterator();while (it.hasNext()) {  process(it.next());   // the client has no idea what is inside the list}

Celý priebeh v texte (11 krokov)
  1. Zoznam drží tri prvky. Ako presne — v poli, v spájanom zozname, v strome — klienta nezaujíma a nikdy sa to nedozvie.
  2. Iterátor je jediné, čo o vnútri zoznamu vie. Klient drží jeho a nič iné — kolekciu nevolá ani raz.
  3. Klient povie iterátoru: daj ďalší.
  4. Iterátor sa nastaví na prvý prvok. Prvok zostáva v zozname — von ide len to, kde iterátor práve stojí.
  5. Druhé volanie. To isté ako predtým, klient nič nepočíta a nič si nepamätá.
  6. A kurzor sa posunie. Pozíciu si drží iterátor, nie kolekcia a nie klient — preto môžu nad tým istým zoznamom bežať aj dva prechody naraz.
  7. Tretie volanie.
  8. Kurzor na treťom prvku.
  9. Štvrté volanie — klient sa pýta, či je ešte niečo.
  10. Za tretím prvkom už nič nie je. Kurzor sa nikam neposunie a iterátor povie, že prechod skončil.
  11. Klient prešiel celú kolekciu a ani raz sa nedotkol jej vnútra — všetky tri prvky sú stále tam, kde boli. Vymeňte zoznam za strom a klientov kód sa nezmení ani o písmeno.

Kedy použiť

  • Pole, spájaný zoznam aj strom sa prechádzajú tým istým kódom.
  • Vnútro kolekcie má zostať skryté — inak by ho musela vydať von.
  • Nad jednou kolekciou beží viac prechodov naraz a každý si drží vlastnú pozíciu.
  • Dopredu, dozadu, po listoch, po úrovniach — každý prechod je vlastný iterátor.
  • Pri veľkej alebo nekonečnej postupnosti sa prvky dajú brať len po jednom.

Pasce

  • Zmena kolekcie počas prechodu rozbije pozíciu a iterátora nikto neupozorní.
  • Prejdený iterátor sa nedá spustiť znova — druhý pokus vráti prázdno bez chyby.
  • Iterátor pozná vnútro kolekcie, takže zmena uloženia znamená prepísať aj jeho.
  • Zamieňa sa s Composite: ten prechádza strom sám zvnútra, iterátor ho riadi zvonku.
  • Rovnako vyzerajúci prechod má nad poľom a nad spájaným zoznamom celkom inú cenu.