Iterator 디자인 패턴은 행위 패턴 중 하나입니다. Iterator 패턴은 객체 그룹을 횡단하는 표준 방법을 제공하는 데 사용됩니다. Iterator 패턴은 널리 Java Collection Framework에서 사용됩니다. Iterator 인터페이스는 컬렉션을 횡단하기 위한 메서드를 제공합니다.
Iterator Design Pattern
GoF에 따르면 iterator 디자인 패턴의 의도는 다음과 같습니다:
배치 객체의 요소에 액세스하는 방법을 제공하되 그 하부 표현을 노출하지 않습니다.
Iterator 패턴은 컬렉션을 횡단하는 것뿐만 아니라 우리의 요구에 따라 다양한 종류의 반복자를 제공할 수 있습니다. Iterator 디자인 패턴은 컬렉션을 횡단하는 실제 구현을 숨기고 클라이언트 프로그램은 반복자 메서드만 사용합니다.
Iterator Pattern Example
package com.journaldev.design.iterator;
public enum ChannelTypeEnum {
ENGLISH, HINDI, FRENCH, ALL;
}
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;
}
}
package com.journaldev.design.iterator;
public interface ChannelCollection {
public void addChannel(Channel c);
public void removeChannel(Channel c);
public ChannelIterator iterator(ChannelTypeEnum type);
}
ChannelCollection 인터페이스는 컬렉션 클래스 구현에 대한 계약을 정의합니다. 채널을 추가하고 제거하는 메서드가 있지만 채널 목록을 반환하는 메서드는 없음에 유의하세요. ChannelCollection에는 순회를 위한 반복자를 반환하는 메서드가 있습니다. ChannelIterator 인터페이스는 다음과 같은 메서드를 정의합니다; ChannelIterator.java
package com.journaldev.design.iterator;
public interface ChannelIterator {
public boolean hasNext();
public Channel next();
}
이제 기본 인터페이스와 핵심 클래스가 준비되었으므로 컬렉션 클래스와 반복자의 구현으로 진행합시다. ChannelCollectionImpl.java
package com.journaldev.design.iterator;
import java.util.ArrayList;
import java.util.List;
public class ChannelCollectionImpl implements ChannelCollection {
private List<Channel> 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<Channel> channels;
private int position;
public ChannelIteratorImpl(ChannelTypeEnum ty,
List<Channel> 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;
}
}
}
내부 클래스의 반복자 인터페이스 구현에 주목하여 해당 구현이 다른 컬렉션에서 사용될 수 없도록합니다. 컬렉션 클래스도 동일한 접근 방식을 따르며 모두 Iterator 인터페이스의 내부 클래스 구현이 있습니다. 컬렉션 및 반복자를 사용하여 컬렉션을 통해 순회하는 간단한 반복자 패턴 테스트 프로그램을 작성해 봅시다. IteratorPatternTest.java
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("******");
// 채널 유형 반복자
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에서의 Iterator 디자인 패턴
우리는 모두 컬렉션 프레임워크 Iterator가 iterator 패턴의 최고의 예인 것을 알고 있지만, java.util.Scanner
클래스도 Iterator 인터페이스를 구현한다는 것을 알고 계셨나요? 이 포스트를 읽어보세요 Java Scanner Class. 반복자 디자인 패턴에 대한 모든 내용은 여기까지입니다. 이것이 도움이 되고 이해하기 쉬울 것을 바랍니다.
Source:
https://www.digitalocean.com/community/tutorials/iterator-design-pattern-java