개념
•
반복자 패턴은 일련의 데이터 집합에 대해 순회를 지원하는 패턴이다.
◦
데이터 집합이란 객체들을 그룹으로 묶어 자료의 구조를 취하는 컬렉션을 말한다.
◦
대표적으로 리스트, 트리, 그래프 등이 있다.
•
트리와 같은 비선형 자료 컬렉션들을 순회하는 알고리즘 전략을 정의하는 것을 반복자 패턴이라고 한다.
구조
•
Aggregate(Interface) : ConcreateIterator 객체를 반환하는 인터페이스를 제공한다.
interface Aggregate {
Iterator iterator();
}
C#
복사
◦
iterator(): ConcreateIterator 객체를 만드는 팩토리 메소드다.
•
ConcreateAggregate(Class): 여러 요소들이 이루어져 있는 데이터 집합체
class ConcreteAggregate implements Aggregate {
Object[] arr;
int index = 0;
public ConcreteAggregate(int size) {
this.arr = new Object[size];
}
public void add(Object o) {
if(index < arr.length) {
arr[index] = o;
index++;
}
}
@Override
public Iterator iterator() {
return new ConcreteIterator(arr);
}
}
C#
복사
•
Iterator(interface): 집합체 내의 요소들을 순서대로 검색하기 위한 인터페이스를 제공한다.
interface Iterator {
boolean hasNext();
Object next();
}
C#
복사
◦
hasNext(): 순회할 다음 요소가 있는지 확인한다.
◦
next(): 요소를 반환하고 다음 요소를 반환할 준비를 하기 위해 커서를 이동시킨다.
•
ConcreateIterator(Class): 반복자 구현 객체다.
class ConcreteIterator implements Iterator {
Object[] arr;
private int nextIndex = 0;
public ConcreteIterator(Object[] arr) {
this.arr = arr;
}
@Override
public boolean hasNext() {
return nextIndex < arr.length;
}
@Override
public Object next() {
return arr[nextIndex++];
}
}
C#
복사
◦
ConcreateAggregate가 구현한 메소드로부터 생성되며 ConcreateAggregate의 컬렉션을 참조하여 순회한다.
◦
어떤 전략으로 순회할지에 대한 로직을 구체화한다.
특징
•
패턴 사용 시기
◦
컬렉션에 상관없이 객체 접근 순회 방식을 통일하고자 할 때
◦
컬렉션을 순회하는 다양한 전략을 지원하고 싶을 때
◦
컬렉션의 복잡한 내부 구조의 구현을 다른 객체로부터 숨기고 싶은 경우
◦
데이터 저장 컬렉션의 종류가 변경될 가능성이 있을 때
•
장점
◦
일관된 이터레이터 인터페이스를 사용해 여러 형태의 컬렉션에 대해 동일한 순회 방법을 제공한다.
◦
컬렉션의 내부 구조 및 순회 방식을 알지 않아도 된다.
◦
집합체의 구현과 접근하는 처리 부분을 반복자 객체로 분리 결합도를 줄일 수 있다.
▪
외부 객체에서 iterator로 접근하기 때문에 ConcreteAggregate 내에 수정 사항이 생겨도 iterator에 문제가 없다면 문제가 발생하지 않는다.
◦
순회 알고리즘을 별도의 반복자 객체에 추출하여 각 클래스의 책임을 분리하여 단일 책임 원칙을 준수한다.
◦
데이터 저장 컬렉션 종류가 변경되어도 클라이언트 구현 코드는 손상되지 않아 수정에는 닫혀 있어 개방 폐쇄 원칙을 준수한다.
•
단점
◦
클래스가 늘어나고 복잡도가 증가한다.
◦
만일 앱이 간단한 컬렉션에서만 작동하는 경우 패턴을 적용하는 것은 복잡도만 증가할 수 있다.
◦
이터레이터 객체를 만드는 것이 유용한 상황인지 판단할 필요가 있다.구현 방법에 따라 캡슐화를 위배할 수 있다.