Страницы

Поиск по вопросам

пятница, 24 января 2020 г.

Стоит ли применять паттерн итератор

#java #шаблоны_проектирования #итераторы


Доброго времени суток.

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


Ответы

Ответ 1



Общие рекомендации Стоит сделать либо один класс с несколькими методами, предоставляющими выборки, либо несколько классов, по одному на вид выборки, и раздать их потребителям. Каждый метод выборки должен возвращать специализированный итератор. Но интерфейсы у итераторов будут одинаковыми: это обычный Java-интерфейс Iterator. По поводу выборки прямоугольной области и двойных итераций по строкам: Стоит сделать так: метод выборки возвращает итератор по объектам типа Row (добавьте какой-либо свой префикс), реализующий интерфейс Iterable. Каждый такой объект имеет ссылку на строку данных и поля first и length, и из него можно получить итератор по такому "слайсу". Таким образом можно итерироваться и по строкам и по элементам: Iterable rows = someQuerier.getRect(left, top, width, height); for (RectRow row : rows) { // многократный проход по одной и той же строке for (int rowPassCount = 0; rowPassCount < maxRowPassCount; rowPassCount += 1) { for (YourItem item : row) { // Ваши действия с элементом } } }

Комментариев нет:

Отправить комментарий