1 분 소요


Iterator Pattern

이터레이터 패턴은 반복자를 사용해서 컬렉션과 같은 데이터 집합의 각 요소들을 순차적으로 접근할 수 있도록 해주는 디자인패턴이다. 자료형의 종류와 구조에 상관없이 하나의 인터페이스로 순회가 가능하다는 특징이 있다.

img1

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 특징

언제 쓸까?

  1. 컬렉션 종류에 상관없이 객체 접근 순회 방식을 통일하고 싶을 때
  2. 컬렉션의 순회 방식을 다양하게 하고 싶을 때 ex) 깊이우선, 넓이우선
  3. 컬렉션 내부 구조를 클라이언트에게 숨기고 싶을 때
  4. 데이터를 저장하는 컬렉션의 종류에 변경 가능성이 존재할 때

장점

  1. 일관된 인터페이스를 사용해서 여러 컬렉션을 조회할 수 있다.
  2. 컬렉션 내부 구조를 몰라도 사용이 가능하다.
  3. 순회 알고리즘을 별도로 분리해서 SRP를 준수한다.
  4. 데이터 컬렉션 종류가 변경되도 클라이언트 코드의 수정이 발생하지 않는다. OCP 준수

단점

  1. 클래스가 늘어나고 복잡도가 높아진다.