Ітератор — це поведінковий патерн, що дозволяє послідовно обходити складну колекцію, не розкриваючи деталі її реалізації.
Завдяки Ітераторові, клієнт може обходити різні колекції в один і той же спосіб, використовуючи єдиний інтерфейс ітераторів.
Складність:
Популярність:
Застосування: Патерн можна часто зустріти в Ruby-коді, особливо в програмах, що працюють з різними типами колекцій, коли потрібно виконати обхід різних сутностей.
Ознаки застосування патерна: Ітератор легко визначити за методами навігації (наприклад, отримання наступного/попереднього елементу і т. д.). Код, який використовує ітератор, часто взагалі не має посилань на колекцію, з якою працює ітератор. Ітератор або приймає колекцію в параметрах конструктора під час створення, або повертається до самої колекцією.
Концептуальний приклад
Цей приклад показує структуру патерна Ітератор , а саме — з яких класів він складається, які ролі ці класи виконують і як вони взаємодіють один з одним.
main.rb: Приклад структури патерна
class AlphabeticalOrderIterator
# In Ruby, the Enumerable mixin provides classes with several traversal and
# searching methods, and with the ability to sort. The class must provide a
# method each, which yields successive members of the collection.
include Enumerable
# This attribute indicates the traversal direction.
attr_accessor :reverse
private :reverse
# @return [Array]
attr_accessor :collection
private :collection
# @param [Array] collection
# @param [Boolean] reverse
def initialize(collection, reverse: false)
@collection = collection
@reverse = reverse
end
def each(&block)
return @collection.reverse.each(&block) if reverse
@collection.each(&block)
end
end
class WordsCollection
# @return [Array]
attr_accessor :collection
private :collection
def initialize(collection = [])
@collection = collection
end
# The `iterator` method returns the iterator object itself, by default we
# return the iterator in ascending order.
def iterator
AlphabeticalOrderIterator.new(@collection)
end
# @return [AlphabeticalOrderIterator]
def reverse_iterator
AlphabeticalOrderIterator.new(@collection, reverse: true)
end
# @param [String] item
def add_item(item)
@collection << item
end
end
# The client code may or may not know about the Concrete Iterator or Collection
# classes, depending on the level of indirection you want to keep in your
# program.
collection = WordsCollection.new
collection.add_item('First')
collection.add_item('Second')
collection.add_item('Third')
puts 'Straight traversal:'
collection.iterator.each { |item| puts item }
puts "\n"
puts 'Reverse traversal:'
collection.reverse_iterator.each { |item| puts item }
output.txt: Результат виконання
Straight traversal:
First
Second
Third
Reverse traversal:
Third
Second
First
Ітератор іншими мовами програмування