В этой статье я расскажу вам историю о старике в деревне, и к концу этой истории вы поймете, что такое шаблон итератора и как он работает!

Давным-давно в деревне жил старик, который работал в продовольственном магазине. Его работа заключалась в том, чтобы получать товары с ферм и продавать продукты сельским жителям. Это происходило каждую неделю: фермеры доставляли продукты в лавку старика, а на следующий день все жители деревни выстраивались перед лавкой старика, чтобы купить продукты.

Старик занимается этим много лет, и у него есть такая система. Его журнал регистрации, чтобы записывать, кто получил их провизию и сколько они ему заплатили. Но для того, чтобы эта система работала, старику нужно было, чтобы жители деревни выстроились в ряд перед магазином, чтобы получить провизию.

И это было проблемой. Система старика означала, что все жители деревни должны были часами стоять в очереди за едой и пайками. Обычно стояла длинная очередь людей, стоящих на солнце, пока старик медленно принимал каждого покупателя, записывал свои записи в своем журнале. Им приходилось входить в офис один за другим, чтобы собрать провизию, но только после нескольких часов ожидания в очереди! Это было тяжело, особенно для пожилых людей. Жители деревни умоляли старика придумать для них другой способ купить провизию, но старик не хотел ничего слышать. Он все время повторял: «Но это же моя система! Вот как я годами раздавал провизию! И я не хочу это менять ». Люди хотели, чтобы кто-то мог им помочь.

Возможное решение

Так случилось, что один деревенский мальчик работал помощником старика. Его работа заключалась в том, чтобы помогать старику, а также управлять очередью жителей деревни за пределами магазина.

Он каждый раз видел, как сельские жители выстраиваются в очередь и борются, и он хотел сделать что-нибудь, чтобы помочь им - в то же время не заставляя старика менять систему, которой он руководил годами.

Он мог очень легко разработать систему с деревенскими жителями, которая позволяла бы каждому оставаться в своих домах, пока не подошла их очередь собирать провизию. Может быть, сработает система токенов на основе чисел. Но как бы он реализовал что-то подобное, чтобы старик не должен был ничего менять, или, предпочтительно, даже ничего об этом не зная?

Однажды ему в голову пришла идея. Он подошел к старику и сказал: «Ну, как насчет того, чтобы просто посидеть в своем магазине и позволить мне впускать людей одного за другим. Я знаю, что вам нравится впускать клиентов одного за другим без каких-либо перерывов. Итак, не торопитесь и, когда будете готовы, просто скажите «Далее». Я позабочусь о том, чтобы привести к вам следующего человека в очереди. Тебе бы это понравилось?"

Старик подумал об этом, и ему показалось, что это отличная идея. Итак, он соглашается и говорит: «Конечно, давайте сделаем это с этого момента».

Итак, на следующий день мальчик, как обычно, заставил людей стоять в очереди. Когда старик крикнул «Далее» из офиса, мальчик пригласил человека в верхней части очереди. И когда он закончил и был готов к следующий человек, старик снова кричит «Далее», и мальчик впускает следующего человека в очереди.

Время перемен

Проделав это пару дней и убедившись, что старик счастлив и все работает нормально, мальчик собирает всех жителей деревни на секретную встречу и рассказывает им свой план. Они вместе планируют систему жетонов на основе чисел, чтобы каждый мог оставаться дома, кроме тех случаев, когда приближается их очередь. План утвержден, и они начинают действовать на следующий день.

Старик, как и в любой другой день, кричит «Далее», когда готов к встрече со следующим человеком. И мальчик с сельскими жителями успевает убедиться, что вошел хоть один человек, когда раздается сигнал «Далее». Старик до сих пор продолжает использовать свою систему регистрации и обслуживания клиентов. Но мальчик незаметно изменил всю реализацию этой системы, так что старик не узнал ни одной детали. Фактически, этот контракт, который мальчик заключил со стариком, настолько великолепен, что жители деревни могут постоянно оптимизировать свою систему для своего удобства. Пока мальчик может ввести следующего человека, когда старик кричит «Далее», существующая система старика все еще работает, и он даже не заметит разницы.

Понимание паттерна

Мальчик и жители деревни придумали то, что в программировании называется шаблоном итератора. Вы можете увидеть шаблон итератора в действии на различных языках и платформах, включая Java и JavaScript.

Например, в Java у нас есть различные типы коллекций, с которыми нам нужно иметь дело при программировании. Некоторые коллекции, например массивы и списки, являются последовательными. Это приказ. Есть некоторые другие коллекции, такие как Наборы, для которых может не быть заданного порядка. Это, конечно, здорово, потому что мы хотим выбрать правильную структуру данных для работы. Но что происходит, когда вам нужно перебрать каждый элемент в данной коллекции? Что ж, для массивов и списков вам нужно выполнить цикл в одном направлении. С помощью Sets вам нужно выполнить цикл по-другому. Для другого типа коллекции это что-то другое?

Это не идеально. Может ли существовать стандартный способ перебора всех элементов коллекции, не беспокоясь о том, как элементы в коллекции хранятся, извлекаются или управляются?

Вы угадали! Вы можете сделать это с помощью шаблона итератора. Для каждого типа коллекции можно создать специальный объект-итератор. Задача объекта-итератора - просто иметь метод, который дает вам следующий объект в коллекции. По сути, это мальчик, говорящий старику: «Эй, не беспокойся о том, что лежит в основе коллекции. Все, что вам нужно в любой момент, - это просто элемент next ».

Все, что вам нужно для каждого прохода итерации в любой момент, - это просто следующий элемент.

Итак, у ArrayList есть итератор, который знает, как вернуть следующий элемент в ArrayList. У набора есть собственный итератор, который знает, как получить следующий элемент в наборе. Человек, вызывающий итератор, не должен заботиться или знать, какова основная реализация. Если вы пишете код, который использует итератор, вы можете использовать этот код для итерации по коллекции, независимо от внутренней реализации коллекции.

В JavaScript также есть итератор, который снова является объектом с методом next () на нем.

Вы можете создавать собственные реализации итератора, которые возвращают «следующий» элемент при вызове next, независимо от того, каким будет этот следующий элемент для конкретного варианта использования.

Зная, когда остановиться

И последнее, что я оставлю вам, это то, что шаблон итератора также может сигнализировать, когда сборка завершена. Что, если кто-то будет продолжать звонить в следующий раз? Итератору нужен какой-то способ связи, когда больше не осталось элементов. В разных языках программирования это делается по-разному. У итератора Java есть метод hasNext, который возвращает false, только если коллекция пуста. Некоторые другие реализации шаблона итератора, такие как, например, JavaScript, возвращают флаг готовности, когда он возвращает последний элемент в коллекции. Как бы то ни было, это, по сути, способ как-то сказать вызывающему, чтобы он не звонил «следующий» вечно.

Хорошо, теперь, когда жители деревни решили проблему условий с помощью шаблона итератора, и теперь, когда вы знаете, что такое шаблон итератора, подумайте о том, где вы можете применить шаблон итератора в своем коде, чтобы упростить процесс итерации по кучу данных. . Есть ли способ создать API, чтобы код, выполняющий итерацию, мог не знать о реализации и вместо этого просто вызывать «Next»?