[디자인패턴] 반복자 패턴
Iterator Pattern
이터레이터 패턴은 반복자를 사용해서 컬렉션과 같은 데이터 집합의 각 요소들을 순차적으로 접근할 수 있도록 해주는 디자인패턴이다. 자료형의 종류와 구조에 상관없이 하나의 인터페이스로 순회가 가능하다는 특징이 있다.
Aggregate
: ConcreateAggreate 객체를 반환하는 인터페이스를 제공
- iterator() : ConcreateIterator 객체를 만드는 팩토리 메서드
ConcreateAggregate
: 데이터의 집합체
iterator
: 집합체 안의 요소들을 순서대로 조회하기 위한 인터페이스 제공
- hasNext() : 순회할 다음 요소가 있는지 확인
- next() : 요소를 반환하고 다음 요소를 반환하기 위해 커서를 이동
ConcreateIterator
: 반복자 객체
- ConcreateAggreate가 구현한 메서드로부터 생성, ConcreateAggreate 의 컬렉션을 참조하여 순회
- 어떤 전략으로 순회할지에 대한 로직이 구현됨.
Iterator Pattern 구현
interface Aggregate {
Iterator iterator();
}
//예제를 단순화하기 위해서 내부
class ConcreateAggreate implements Aggreate {
Object[] arr;
int idx = 0;
public ConcreateAggreate(int size) {
this.arr = new Object[size];
}
public void add(Object o) {
if(idx < arr.length) {
arr[idx] = o;
idx++;
}
}
@Override
public Iterator iterator() {
return new ConcreateIterator(arr);
}
}
interface Iterator {
boolean hasNext();
Object next();
}
class ConcreateIterator implements Iterator {
Object[] arr;
private int nextIdx = 0;
public ConcreateIterator(Object[] arr) {
this.arr = arr;
}
@Override
public boolean hasNext() {
return nextIdx < arr.length;
}
@Override
public Object next() {
return arr[nextIdx++];
}
}
- 이 예제는 배열로 구현했지만
Aggreate
를 인터페이스로 분리했기 때문에ConcreateAggreate
의 코드를 변경하지 않고도 다른Iterator
를 적용할 수 있다. 그리고Iterator
도 인터페이스화 했기 때문에 기존 코드를 바꾸지 않고도 새로운 순회 방식을 추가할 수 있다.
Iterator Pattern 특징
언제 쓸까?
- 컬렉션 종류에 상관없이 객체 접근 순회 방식을 통일하고 싶을 때
- 컬렉션의 순회 방식을 다양하게 하고 싶을 때 ex) 깊이우선, 넓이우선
- 컬렉션 내부 구조를 클라이언트에게 숨기고 싶을 때
- 데이터를 저장하는 컬렉션의 종류에 변경 가능성이 존재할 때
장점
- 일관된 인터페이스를 사용해서 여러 컬렉션을 조회할 수 있다.
- 컬렉션 내부 구조를 몰라도 사용이 가능하다.
- 순회 알고리즘을 별도로 분리해서
SRP
를 준수한다. - 데이터 컬렉션 종류가 변경되도 클라이언트 코드의 수정이 발생하지 않는다.
OCP
준수
단점
- 클래스가 늘어나고 복잡도가 높아진다.