반복자 패턴이란?
반복자 패턴은 자세한 표현방법을 나타내지 않고, 객체 집합의 요소들을 순차적으로 접근하게 하는데 사용한다. 별도의 이터레이터 객체를 반환 받아 이를 이용해 순회하기 때문에, 집합체의 내부 구조를 노출하지 않고 순회 할 수 있다는 장점이 있고, 리스트 객체와 방문하는 프로세스 사이의 결합을 줄인다.
자바의 컬렉션 프레임워크(JCF)에서 각종 컬렉션을 무리없이 순회할수 있는 것도 내부에 미리 이터레이터 패턴이 적용되어 있기 때문이다.
반복자 패턴 사용 법
- Aggregate (인터페이스) : Iterator의 집합체 컬렉션으로, ConcreateIterator 객체를 반환하는 인터페이스를 제공한다.
- ConcreateAggregate (클래스) : Aggregate를 구현하는 집합체 구현체
- Iterator (인터페이스) : 집합체 내의 요소들을 순서대로 검색하기 위한 인터페이스를 제공한다.
- hasNext() : 순회할 다음 요소가 있는지 확인 (true / false)
- next() : 요소를 반환하고 다음 요소를 반환할 준비를 하기 위해 커서를 이동시킴
- ConcreateIterator (클래스) : Iterator를 구현하는 반복자 객체
- ConcreateAggregate가 구현한 메서드로부터 생성되며, ConcreateAggregate 의 컬렉션을 참조하여 순회한다.
- 어떤 전략으로 순회할지에 대한 로직을 구체화 한다.
public interface Aggregate {
Iterator createIterator();
}
public class ConcreteAggregate implements Aggregate {
private Object[] items;
private int size;
public ConcreteAggregate(int size) {
this.items = new Object[size];
this.size = size;
}
public void setItem(int index, Object item) {
items[index] = item;
}
@Override
public Iterator createIterator() {
return new ConcreteIterator(this);
}
public Object getItem(int index) {
return items[index];
}
public int getSize() {
return size;
}
}
public interface Iterator<T> {
boolean hasNext();
T next();
}
public class ConcreteIterator implements Iterator<Object> {
private ConcreteAggregate aggregate;
private int currentIndex;
public ConcreteIterator(ConcreteAggregate aggregate) {
this.aggregate = aggregate;
this.currentIndex = 0;
}
@Override
public boolean hasNext() {
return currentIndex < aggregate.getSize();
}
@Override
public Object next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
return aggregate.getItem(currentIndex++);
}
}
public class Client {
public static void main(String[] args) {
ConcreteAggregate aggregate = new ConcreteAggregate(10);
for (int i = 0; i < 10; i++) {
aggregate.setItem(i, "Item " + i);
}
Iterator iterator = aggregate.createIterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
}
패턴 사용 시기
- 컬렉션에 상과없이 객체 접근 순회 방식을 통일하고자 할 때
- 컬렉션을 순회하는 다양한 방법을 지원하고 싶을 때
- 컬렉션의 복잡한 내부 구조를 클라이언트로부터 숨기고 싶은 경우
- 데이터 저장 컬렉션 종류가 변경 가능성이 있을 때
패턴 장점
- 일관된 이터레이터 인터페이스를 사용해 여러 형태의 컬렉션에 대해 동일한 순회 방법을 제공한다.
- 컬렉션의 내부 구조 및 순회 방식을 알지 안항도 된다.
- 집합체의 구현과 접근하는 처리 부분을 반복자 객체로 분리해 결합도를 줄일 수 있다.
- 순회 알고리즘을 별도의 반복자 객체에 추출해 각 클래스의 책임을 분리해 SRP를 준수
- 데이터 저장 컬렉션 종류가 변경되어도 클라이언트 구현 코드는 손상되지 않아 수정에는 닫혀 있어 OCP를 준수
패턴 단점
- 클래스가 늘어나고 복잡도가 증가한다.
- 구현 방법에 따라 캡슐화를 위배할 수 있다.
'CS > Design Pattern' 카테고리의 다른 글
리팩토링 (2) | 2024.06.10 |
---|---|
데코레이터 패턴 (Decorater Pattern) (0) | 2024.06.10 |
커맨드 패턴 (Command Pattern) (0) | 2024.06.10 |
전략 패턴, 스트래티지 패턴 (Strategy Pattern) (0) | 2024.06.10 |
상태 패턴 (State pattern) (0) | 2024.06.10 |