Ітератор

Аналогія

Гарний приклад – радіоприймач. Ви починаєте з якоїсь радіостанції, а потім переміщаєтеся станціями вперед/назад. Тобто пристрій надає інтерфейс для ітерування каналами.

Стисло

Шаблон - це спосіб доступу до елементів об'єкта без розкриття базового представлення.

Вікіпедія

У цьому шаблоні ітератор використовується для переміщення контейнера та забезпечення доступу до елементів контейнера. Шаблон має на увазі відділення алгоритмів від контейнера. У деяких випадках алгоритми, специфічні при цьому контейнера, неможливо знайти відокремлені.

Приклад

PHP досить легко реалізувати цей шаблон за допомогою стандартної бібліотеки PHP. Спочатку створимо радіостанцію RadioStation.

class RadioStation
{
    protected $frequency;

    public function __construct(float $frequency)
    {
        $this->frequency = $frequency;
    }

    public function getFrequency(): float
    {
        return $this->frequency;
    }
}

Тепер створимо ітератор:

use Countable;
use Iterator;

class StationList implements Countable, Iterator
{
    /** @var RadioStation[] $stations */
    protected $stations = [];

    /** @var int $counter */
    protected $counter;

    public function addStation(RadioStation $station)
    {
        $this->stations[] = $station;
    }

    public function removeStation(RadioStation $toRemove)
    {
        $toRemoveFrequency = $toRemove->getFrequency();
        $this->stations = array_filter($this->stations, function (RadioStation $station) use ($toRemoveFrequency) {
            return $station->getFrequency() !== $toRemoveFrequency;
        });
    }

    public function count(): int
    {
        return count($this->stations);
    }

    Public function current(): RadioStation
    {
        return $this->stations[$this->counter];
    }

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

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

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

    public function valid(): bool
    {
        return isset($this->stations[$this->counter]);
    }
}

Використання:

$ stationList = New StationList ();

$stationList->addStation(new RadioStation(89));
$stationList->addStation(new RadioStation(101));
$stationList->addStation(new RadioStation(102));
$stationList->addStation(new RadioStation(103.2));

foreach($stationList as $station) {
    echo $station->getFrequency() . PHP_EOL;
}

$stationList->removeStation(new RadioStation(89)); // Will remove station 89