Обзор темы [Шаблоны проектирования]

Затем: МотивацияНазначение

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

Затем: СтруктураМотивация

Составной объект типа «список» должен предоставлять возможность обратиться к своим элементам не затрагивая свою внутреннюю структуру. Кроме того, Вы можете захотеть обойти список различными способами, в зависимости от того, что вы хотите сделать. Но Вы вероятно не захотите к засорять интерфейс List операциями для различных обходов списка. Кроме того, возможно, вам понадобится не один экземпляр такого итератора.

Шаблон Iterator позволяет Вам разрешить эту задачу. Идея шаблона состоит в том, чтобы выделить ответственность за доступ, и обход списка и поместить ее в объект iterator. Класс Iterator определяет интерфейс для доступа к элементам списка. Iterator ответствен за слежение за текущим элементом; то есть он знает, которые элементы уже были посещены.

Например, класс List вот так связан с ListIterator:

Прежде, чем Вы сможете инстанцировать ListIterator, Вы должны обеспечить его списком, который надо обходить. Как только у вас появился объект ListIterator, Вы можете обращаться к элементам списка последовательно. Операция CurrentItem возвращает текущий элемент в списке, First инициализирует текущий элемент как первый элемент, Next переходит к следующему, и IsDone говорит, прошли ли мы весь список.

Отделение механизма обхода из объекта List позволяет нам определять итераторы для различных целей без перечисления их в интерфейсе List. Например, FilteringListIterator мог бы обеспечивать доступ только к тем элементам, которые удовлетворяют специфическим условиям фильтра.

Обратите внимание, что iterator и список сдвоены, и клиент должен знать, с каким агрегатом он работает. Было бы лучше, если бы мы могли изменять класс агрегат не изменяя клиентский код. Мы можем добиться этого определяя понятие полиморфный итератор.

Например, пусть SkipList – реализация List. Skiplist - структура данных с характеристиками, подобными сбалансированному дереву. Мы хотим суметь написать код, который работает для объектов List  и SkipList.

Мы определяем класс AbstractList, который обеспечивает общий интерфейс, управляющий списками. Точно так же мы должны описать Iteratorclass, который определяет общий интерфейс итератора. Затем мы можем определить конкретные подклассы Iterator для различных реализаций списка. В результате, итеративный механизм становится независящим от класса агрегата.

Остаётся ещё одна задача - как создать итератор. Так как мы хотим писать код, независящий от конкретного подкласса List, мы не можем просто инстанцировать определенный класс. Вместо этого, мы делаем объекты List ответственными за создание соответствующего итератора. Для этого необходимо описать операцию CreateIterator, с помощью которой клиент запрашивает объект - итератор.

CreateIterator - пример метода фабрики (см. Метод Фабрики ). Мы используем его здесь, чтобы позволить клиенту запрашивать у объекта списка соответствующий итератор. Фабрика описывает две иерархии классов, первую для списков, вторю для итераторов. CreateIterator метод фабрики "соединяет" эти иерархии.

 

Затем: Составные частиСтруктура

Составные части