Паттерн Итератор

Паттерн Итератор — очень часто используемый шаблон проектирования в средах программирования Java и .Net.

Паттерн Итератор предоставляет способ последовательного доступа к элементам агрегированного объекта без раскрытия его внутреннего представления.

Паттерн Итератор — это поведенческий паттерн.

Введение

назначение

Позволяет последовательно обращаться к элементам агрегированного объекта, не раскрывая внутреннее представление объекта.

Основные решаемые проблемы

  • Предоставляет унифицированный метод для обхода различных агрегированных объектов.

Сценарий использования

  • Когда требуется обойти агрегированный объект, не раскрывая его внутреннюю структуру.

Подход к реализации

  • Определите интерфейс итератора: containshasNext()иnext()и другие методы, используемые для обхода элементов.
  • Создайте конкретный итератор: реализует интерфейс итератора и определяет, как обходить конкретный агрегированный объект.
  • Класс-агрегат: Определяет интерфейс для возврата объекта-итератора.

Ключевой код

  • Интерфейс итератора: Задает методы обхода элементов.
  • Конкретный итератор: Реализует интерфейс итератора и содержит логику обхода.

Пример приложения

  • Iterator в Java: Итераторы в Java Collections Framework используются для обхода элементов коллекции.

Преимущества

  1. Поддерживает несколько методов обхода.: Разные итераторы могут определять разные методы обхода.
  2. Упрощение класса-агрегата: Классу-агрегату не нужно заботиться о логике обхода.
  3. Поддержка множественного обхода: Можно одновременно выполнять несколько обходов одного и того же агрегатного объекта.
  4. Расширяемость: Добавлять новые классы-агрегаты и классы итераторов очень удобно без изменения существующего кода.

Недостатки

  • Сложность системы: Каждый раз при добавлении класса-агрегата нужно добавить соответствующий класс итератора, что увеличивает количество классов.

Рекомендации по использованию

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

Примечания

  • Паттерн «Итератор» отделяет поведение обхода объектов коллекции, позволяя внешнему коду прозрачно получать доступ к внутренним данным коллекции, не раскрывая её внутреннюю структуру.

Структура

Паттерн Итератор включает следующие основные роли:

  • Интерфейс итератора (Iterator): Определяет методы для доступа и обхода каждого элемента в агрегатном объекте, обычно включая получение следующего элемента, проверку наличия следующих элементов, получение текущей позиции и другие методы.

  • Конкретный итератор (Concrete Iterator): Реализует интерфейс итератора и отвечает за обход и доступ к агрегатному объекту, записывая текущую позицию обхода.

  • Интерфейс агрегата (Aggregate): Определяет интерфейс для создания объектов-итераторов, обычно включающий фабричный метод для создания объектов-итераторов.

  • Конкретный агрегат (Concrete Aggregate): Реализует интерфейс агрегата и отвечает за создание конкретных объектов-итераторов и предоставление данных для обхода.

Реализация

Мы создадим интерфейс, описывающий методы навигации.Iteratorинтерфейс и интерфейс, возвращающий итератор.ContainerИнтерфейс. РеализованныйContainerКонкретные классы интерфейса будут отвечать за реализацию.IteratorИнтерфейс.

IteratorPatternDemo, наш демонстрационный класс использует конкретный класс.NamesRepositoryДля выводаNamesRepositoryХранится в виде коллекции вNames。

迭代器模式的 UML 图

Шаг 1

Создание интерфейса:

Iterator.java

public interface Iterator { public boolean hasNext(); public Object Далее(); }

Container.java

public interface Container { public Iterator getIterator(); }

Шаг 2

Создайте реализациюContainerконкретный класс интерфейса. Этот класс реализовал.IteratorВнутренний класс интерфейсаNameIterator。

NameRepository.java

public class NameRepository implements Container { public String[] names = {"Robert" , "John" ,"Julie" , "Lora"}; @Override public Iterator getIterator() { return new NameIterator(); } private class NameIterator implements Iterator { int index; @Override public boolean hasNext() { if(index < names.length){ return true; } return false; } @Override public Object next() { if(this.hasNext()){ return names[index++]; } return null; } } }

Шаг 3

ИспользованиеNameRepositoryдля получения итератора и вывода имён.

IteratorPatternDemo.java

public class IteratorPatternDemo { public static void main(String[] args) { NameRepository namesRepository = new NameRepository(); for(Iterator iter = namesRepository.getIterator(); iter.hasNext();){ String name = (String)iter.next(); System.out.println("Имя : " + name); } } }

Шаг 4

Запустите программу, выведите результаты:

Name : Robert
Name : John
Name : Julie
Name : Lora
Другие расширения