Перейти к основному содержимому

Что это такое

Паттерн Iterator (итератор) проходит по коллекции, не раскрывая способа её хранения. Вызывающий код запрашивает по одному элементу за раз — а живут ли данные в массиве, в дереве или в базе данных, остаётся внутренним делом коллекции.

В PHP этот паттерн встроен: foreach принимает любой объект, реализующий встроенный интерфейс Iterator, а генератор — функция с yield — реализует его за вас. Для обычных массивов foreach сам и есть итератор; паттерн важен тогда, когда хранение скрыто или обход сложен.


Пример: обход плейлиста

Плейлист держит свои песни приватными. Метод play() — генератор: он отдаёт по одной песне на каждый шаг цикла, поэтому хранилище за ним можно полностью изменить, не сломав ни одного вызывающего кода.

Генератор выдаёт по одной песне за раз

Цикл никогда не обращается к массиву внутри плейлиста. Каждый yield приостанавливает функцию, пока foreach не запросит следующую песню. Замените массив связным списком или ленивой загрузкой — и этот цикл по-прежнему будет работать без изменений.

Prompt
Напишите PHP-скрипт с паттерном Iterator: класс Playlist, который держит массив песен приватным и предоставляет метод-генератор play(), выдающий по одной песне за раз. Пройдите по плейлисту с помощью foreach и выведите каждую песню.
Вывод: PHP-скрипт

Когда применять

Применяйте, когда внутреннее устройство коллекции должно остаться приватным, когда обход нетривиален (деревья, страницы из API) или когда элементы нужно получать лениво, по одному.

Не применяйте для обычных массивов в своём собственном коде — foreach по массиву короче, быстрее и понятен каждому читателю.


Плюсы и минусы

Плюсы: хранилище остаётся приватным и заменяемым; генераторы делают итератор из одной функции; сложный обход пишется один раз.

Минусы: больше механики, чем при обычном проходе по массиву; активный итератор по изменяющейся коллекции — классический источник тонких ошибок.