Cute Running Puppy

JAVA/디자인패턴(GoF)

# 자바 디자인 패턴 입문 - Iterator 패턴 쉽게 이해하기

뭉지맘 2025. 6. 18. 17:54

Iterator 패턴이란?

자료구조의 내부 구조를 몰라도
요소를 하나씩 꺼내서 순회(iterate)할 수 있게 해주는 디자인 패턴이다.

 

왜 Iterator 패턴이 필요할까? 그냥 for문 쓰면 안되나??

물론 가능하다. 하지만 아래 문제점이 있다:

  • 배열, 리스트, 링크드리스트 등 구조마다 for문 다르게 짜야 됨
  • 여러 자료구조를 한 번에 순회하려면 코드 중복이 생김
  • 나중에 자료구조가 바뀌면 for문도 고쳐야 함

➡ 유지보수성, 확장성, 재사용성 부족

 

Iterator 패턴의 핵심 아이디어

"요소 꺼내는 방식을 객체로 분리"
→ 사용자는 next()와 hasNext()만 알면 끝!

Iterator it = bookShelf.iterator();
while (it.hasNext()) {
    Book b = (Book) it.next();
    System.out.println(b.getName());
}

 

  • 내부가 배열이든 리스트든 트리든 관계없음
  • 단일한 방식으로 순회 가능

구조 구성

역할 클래스명 설명
Aggregate BookShelf 책장 전체. 요소 보관
Iterator BookShelfIterator 요소 순회하는 역할
Client Main 사용하는 코드
Element Book 순회할 대상 객체

 

 

<<기본 예제>>

public interface Iterator {
    boolean hasNext();
    Object next();
}

---

public class BookShelf implements Aggregate {
    private List<Book> books = new ArrayList<>();

    public void add(Book book) {
        books.add(book);
    }

    public Book get(int index) {
        return books.get(index);
    }

    public int size() {
        return books.size();
    }

    public Iterator iterator() {
        return new BookShelfIterator(this);
    }
}

---

public class BookShelfIterator implements Iterator {
    private BookShelf shelf;
    private int index = 0;

    public BookShelfIterator(BookShelf shelf) {
        this.shelf = shelf;
    }

    public boolean hasNext() {
        return index < shelf.size();
    }

    public Object next() {
        return shelf.get(index++);
    }
}

 

확장 예시 : 잡지장 추가

public class MagazineShelf implements Aggregate {
    private LinkedList<Magazine> magazines = new LinkedList<>();

    public void add(Magazine m) {
        magazines.add(m);
    }

    public Magazine get(int index) {
        return magazines.get(index);
    }

    public int size() {
        return magazines.size();
    }

    public Iterator iterator() {
        return new MagazineShelfIterator(this);
    }
}

 

이제 두 자료구조 모두 같은방식으로 순회 가능!

printItems(bookShelf.iterator());
printItems(magazineShelf.iterator());

 

instanceof? Object? 왜 쓰는지 헷갈렸다면?

Iterator가 Object를 리턴하니까 실제 객체(Book, Magazine)를 꺼내려면 이렇게 써야 한다.

Object item = it.next();
if (item instanceof Book) {
    System.out.println(((Book) item).getName());
}

→ 하지만 Book, Magazine 모두 getTitle()이라는 공통 메서드를 가진 PrintableItem 인터페이스를 만들면 훨씬 깔끔해진다.

 

 

Iterator 패턴 장점 요약

- 다양한 자료구조를 동일하게 순회 가능
- 내부 구조 숨김 → 캡슐화
- 순회 방식(정방향, 역방향 등)도 유연하게 변경 가능
- 유지보수성과 확장성 매우 좋음

 

실무에서 어디서 쓰이냐?

 

  • 자바 컬렉션 (List, Set, Map) → .iterator() 있음
  • 스프링 프레임워크 내부 AOP, ResultSet 등 다양한 곳에 활용
  • 외부 API, DB, 파일 등 반복 순회 처리할 때 유용