Рубрики
Без рубрики

Шаблон проектирования итератора в Java

Шаблон итератора, Шаблон проектирования итератора в Java. Пример учебника по шаблону Итератора Java. Классы коллекции итераторов hasNext, методы next, исходный код.

Автор оригинала: Pankaj Kumar.

Шаблон проектирования итератора в одном из поведенческих шаблонов. Шаблон итератора используется для обеспечения стандартного способа обхода группы объектов. Шаблон итератора широко используется в Java Collection Framework . Интерфейс итератора предоставляет методы для обхода коллекции.

Шаблон проектирования Итератора

Согласно GoF, целью шаблона проектирования итератора является:

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

Шаблон итератора-это не только прохождение по коллекции, мы можем предоставить различные типы итераторов в зависимости от наших требований.

Шаблон проектирования итератора скрывает фактическую реализацию обхода через коллекцию, и клиентские программы просто используют методы итератора.

Пример Шаблона Итератора

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

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

Здесь мы можем использовать шаблон итератора и обеспечить итерацию в зависимости от типа канала. Мы должны убедиться, что клиентская программа может получить доступ к списку каналов только через итератор.

Первая часть реализации заключается в определении контракта для наших интерфейсов сбора и итератора.

Первая часть реализации заключается в определении контракта для наших интерфейсов сбора и итератора.

package com.journaldev.design.iterator;

public enum ChannelTypeEnum {

	ENGLISH, HINDI, FRENCH, ALL;
}

ChannelTypeEnum-это перечисление java , которое определяет все различные типы каналов.

ChannelTypeEnum-это || перечисление java||, которое определяет все различные типы каналов.

package com.journaldev.design.iterator;

public class Channel {

	private double frequency;
	private ChannelTypeEnum TYPE;
	
	public Channel(double freq, ChannelTypeEnum type){
		this.frequency=freq;
		this.TYPE=type;
	}

	public double getFrequency() {
		return frequency;
	}

	public ChannelTypeEnum getTYPE() {
		return TYPE;
	}
	
	@Override
	public String toString(){
		return "Frequency="+this.frequency+", Type="+this.TYPE;
	}
	
}

Канал-это простой класс POJO, который имеет атрибуты частота и тип канала.

Канал-это простой класс POJO, который имеет атрибуты частота и тип канала.

package com.journaldev.design.iterator;

public interface ChannelCollection {

	public void addChannel(Channel c);
	
	public void removeChannel(Channel c);
	
	public ChannelIterator iterator(ChannelTypeEnum type);
	
}

Интерфейс сбора каналов определяет контракт для реализации нашего класса коллекции. Обратите внимание, что существуют методы добавления и удаления канала, но нет метода, возвращающего список каналов. Коллекция каналов имеет метод, который возвращает итератор для обхода. Интерфейс итератора каналов определяет следующие методы;

Интерфейс сбора каналов определяет контракт для реализации нашего класса коллекции. Обратите внимание, что существуют методы добавления и удаления канала, но нет метода, возвращающего список каналов. Коллекция каналов имеет метод, который возвращает итератор для обхода. Интерфейс итератора каналов определяет следующие методы;

package com.journaldev.design.iterator;

public interface ChannelIterator {

	public boolean hasNext();
	
	public Channel next();
}

Теперь наш базовый интерфейс и основные классы готовы, давайте приступим к реализации класса коллекции и итератора.

Теперь наш базовый интерфейс и основные классы готовы, давайте приступим к реализации класса коллекции и итератора.

package com.journaldev.design.iterator;

import java.util.ArrayList;
import java.util.List;

public class ChannelCollectionImpl implements ChannelCollection {

	private List channelsList;

	public ChannelCollectionImpl() {
		channelsList = new ArrayList<>();
	}

	public void addChannel(Channel c) {
		this.channelsList.add(c);
	}

	public void removeChannel(Channel c) {
		this.channelsList.remove(c);
	}

	@Override
	public ChannelIterator iterator(ChannelTypeEnum type) {
		return new ChannelIteratorImpl(type, this.channelsList);
	}

	private class ChannelIteratorImpl implements ChannelIterator {

		private ChannelTypeEnum type;
		private List channels;
		private int position;

		public ChannelIteratorImpl(ChannelTypeEnum ty,
				List channelsList) {
			this.type = ty;
			this.channels = channelsList;
		}

		@Override
		public boolean hasNext() {
			while (position < channels.size()) {
				Channel c = channels.get(position);
				if (c.getTYPE().equals(type) || type.equals(ChannelTypeEnum.ALL)) {
					return true;
				} else
					position++;
			}
			return false;
		}

		@Override
		public Channel next() {
			Channel c = channels.get(position);
			position++;
			return c;
		}

	}
}

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

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

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

package com.journaldev.design.iterator;

public class IteratorPatternTest {

	public static void main(String[] args) {
		ChannelCollection channels = populateChannels();
		ChannelIterator baseIterator = channels.iterator(ChannelTypeEnum.ALL);
		while (baseIterator.hasNext()) {
			Channel c = baseIterator.next();
			System.out.println(c.toString());
		}
		System.out.println("******");
		// Channel Type Iterator
		ChannelIterator englishIterator = channels.iterator(ChannelTypeEnum.ENGLISH);
		while (englishIterator.hasNext()) {
			Channel c = englishIterator.next();
			System.out.println(c.toString());
		}
	}

	private static ChannelCollection populateChannels() {
		ChannelCollection channels = new ChannelCollectionImpl();
		channels.addChannel(new Channel(98.5, ChannelTypeEnum.ENGLISH));
		channels.addChannel(new Channel(99.5, ChannelTypeEnum.HINDI));
		channels.addChannel(new Channel(100.5, ChannelTypeEnum.FRENCH));
		channels.addChannel(new Channel(101.5, ChannelTypeEnum.ENGLISH));
		channels.addChannel(new Channel(102.5, ChannelTypeEnum.HINDI));
		channels.addChannel(new Channel(103.5, ChannelTypeEnum.FRENCH));
		channels.addChannel(new Channel(104.5, ChannelTypeEnum.ENGLISH));
		channels.addChannel(new Channel(105.5, ChannelTypeEnum.HINDI));
		channels.addChannel(new Channel(106.5, ChannelTypeEnum.FRENCH));
		return channels;
	}

}

Когда я запускаю вышеуказанную программу, она выдает следующий вывод;

Frequency=98.5, Type=ENGLISH
Frequency=99.5, Type=HINDI
Frequency=100.5, Type=FRENCH
Frequency=101.5, Type=ENGLISH
Frequency=102.5, Type=HINDI
Frequency=103.5, Type=FRENCH
Frequency=104.5, Type=ENGLISH
Frequency=105.5, Type=HINDI
Frequency=106.5, Type=FRENCH
******
Frequency=98.5, Type=ENGLISH
Frequency=101.5, Type=ENGLISH
Frequency=104.5, Type=ENGLISH

Важные моменты Шаблона Проектирования Итератора

  • Шаблон итератора полезен, когда вы хотите предоставить стандартный способ перебора коллекции и скрыть логику реализации от клиентской программы.
  • Логика итерации встроена в саму коллекцию, и это помогает клиентской программе легко перебирать их.

Шаблон проектирования итератора в JDK

Мы все знаем, что итератор платформы сбора данных является лучшим примером реализации шаблона итератора, но знаете ли вы, что java.util.Класс Scanner также реализует интерфейс итератора. Прочитайте этот пост, чтобы узнать о Классе сканера Java .

Это все для шаблона проектирования итератора, я надеюсь, что это полезно и легко понять.