안녕하세요! GoF 디자인 패턴 연재, 이번 시간에는 행위 패턴(Behavioral Patterns)의 한 종류로, 컬렉션의 내부 구현을 숨긴 채 그 안의 모든 항목에 접근할 수 있는 방법을 제공하는 이터레이터(Iterator) 패턴에 대해 알아보겠습니다.
정의
이터레이터(Iterator) 패턴은 어떤 컬렉션(Aggregate) 객체의 내부 표현(배열, 리스트, 트리 등)을 외부에 노출시키지 않고, 그 안에 포함된 요소들을 순차적으로 접근할 수 있는 방법을 제공하는 패턴입니다. '이터레이터'는 '반복자'라는 뜻으로, 컬렉션을 순회하는 역할을 전담하는 객체입니다.
TV 리모컨을 생각해봅시다. 우리는 '다음 채널(+)', '이전 채널(-)' 버튼만 누르면 채널을 순서대로 탐색할 수 있습니다. TV 내부에서 채널 목록이 배열로 관리되는지, 리스트로 관리되는지, 혹은 다른 복잡한 구조로 되어 있는지 전혀 알 필요가 없습니다. 리모컨의 버튼이 바로 이터레이터의 next(), hasNext() 와 같은 역할을 하는 것입니다.
이처럼 이터레이터 패턴은 '데이터의 집합(컬렉션)'과 '데이터를 순회하는 행위'를 분리하여, 클라이언트가 컬렉션의 내부 구조에 얽매이지 않고 일관된 방식으로 요소에 접근할 수 있게 해줍니다. 다음과 같이 구성됩니다
- Iterator (이터레이터): 컬렉션을 순회하는 데 필요한 메서드(예: hasNext(), next())의 인터페이스를 정의합니다.
- ConcreteIterator (구체적인 이터레이터): Iterator 인터페이스를 구현하며, 특정 컬렉션을 순회하는 로직을 가집니다. 현재 순회 중인 위치를 기억하고 추적합니다.
- Aggregate (집합체): 이터레이터 객체를 생성하는 메서드(예: createIterator())의 인터페이스를 정의합니다.
- ConcreteAggregate (구체적인 집합체): Aggregate 인터페이스를 구현하며, ConcreteIterator의 인스턴스를 생성하여 반환합니다.
사용예시
다양한 책(Book)들을 보관하고 있는 서재(BookCollection)를 순회하는 예제를 통해 이터레이터 패턴을 구현해 보겠습니다.
1. 이터레이터 (Iterator) 및 집합체 (Aggregate) 인터페이스 정의
먼저 표준 인터페이스들을 정의합니다. (Java에서는 java.util.Iterator와 java.lang.Iterable이 이미 존재하지만, 패턴 학습을 위해 직접 만들어 보겠습니다.)
// Iterator 인터페이스
public interface Iterator<T> {
boolean hasNext();
T next();
}
// Aggregate 인터페이스
public interface Aggregate {
Iterator createIterator();
}
2. 구체적인 집합체 (ConcreteAggregate) 클래스 구현
책들을 배열로 관리하는 BookCollection 클래스를 구현합니다.
// 간단한 Book 클래스
class Book {
private String name;
public Book(String name) { this.name = name; }
public String getName() { return name; }
}
// ConcreteAggregate 클래스
public class BookCollection implements Aggregate {
private Book[] books;
private int last = 0;
public BookCollection(int maxSize) {
this.books = new Book[maxSize];
}
public Book getBookAt(int index) {
return books[index];
}
public void addBook(Book book) {
if (last < books.length) {
this.books[last] = book;
last++;
}
}
public int getLength() {
return last;
}
@Override
public Iterator createIterator() {
return new BookIterator(this);
}
}
3. 구체적인 이터레이터 (ConcreteIterator) 클래스 구현
BookCollection을 순회하는 BookIterator를 구현합니다.
// ConcreteIterator 클래스
public class BookIterator implements Iterator<Book> {
private BookCollection bookCollection;
private int index;
public BookIterator(BookCollection bookCollection) {
this.bookCollection = bookCollection;
this.index = 0;
}
@Override
public boolean hasNext() {
return index < bookCollection.getLength();
}
@Override
public Book next() {
if (this.hasNext()) {
Book book = bookCollection.getBookAt(index);
index++;
return book;
}
return null; // 실제로는 NoSuchElementException을 던지는 것이 좋음
}
}
4. 클라이언트 (Client) 코드
클라이언트는 BookCollection의 내부가 배열인지 전혀 몰라도, 이터레이터를 통해 모든 책을 순회할 수 있습니다.
public class Library {
public static void main(String[] args) {
// 1. 집합체 생성 및 책 추가
BookCollection bookCollection = new BookCollection(5);
bookCollection.addBook(new Book("디자인 패턴의 이해"));
bookCollection.addBook(new Book("클린 코드"));
bookCollection.addBook(new Book("객체지향의 사실과 오해"));
// 2. 이터레이터 생성
Iterator<Book> it = bookCollection.createIterator();
// 3. 이터레이터를 사용하여 순회
while (it.hasNext()) {
Book book = it.next();
System.out.println(book.getName());
}
// 실행 결과:
// 디자인 패턴의 이해
// 클린 코드
// 객체지향의 사실과 오해
}
}
결론
이터레이터는 현대언어에서 다양한 자료 형을 순환하기 위한 직관적인 패턴으로 사용됩니다. 다음의 경우에 이터레이터의 구현을 검토해 볼 수 있습니다
- 컬렉션의 내부 구조를 클라이언트로부터 숨기고 싶을 때: 클라이언트는 Iterator 인터페이스만 알면 되므로, 컬렉션의 내부 구현이 변경되어도 클라이언트 코드는 영향을 받지 않습니다.
- 하나의 컬렉션에 대해 여러 가지 순회 방법을 제공하고 싶을 때: 정방향 이터레이터, 역방향 이터레이터, 특정 조건에 맞는 요소만 반환하는 필터링 이터레이터 등 다양한 이터레이터를 만들 수 있습니다.
- 서로 다른 구조를 가진 여러 컬렉션에 대해 동일한 방식(인터페이스)으로 순회하고 싶을 때
그러나 간단한 순회 로직을 위해 여러 클래스(Iterator, ConcreteIterator 등)를 추가로 만들어야 하므로, 경우에 따라 과설계(Over-engineering)가 될 수 있습니다.
이터레이터 패턴은 컬렉션과 순회 로직을 분리하여 시스템의 결합도를 낮추고 유연성을 높이는 매우 중요한 패턴입니다. Java의 for-each 구문도 내부적으로는 이 이터레이터 패턴을 기반으로 동작합니다. 다음시간에는 자주 등장하는 문제상황을 규격화한, 인터프리터 패턴을 알아보겠습니다
'정보보안-이론 > XX에 대하여' 카테고리의 다른 글
[디자인 패턴] (GoF 행위패턴) State Pattern에 대하여 (0) | 2025.07.12 |
---|---|
[디자인 패턴] (GoF 행위패턴) Interpreter Pattern에 대하여 (0) | 2025.07.12 |
[디자인 패턴] (GoF 행위패턴) Memento Pattern에 대하여 (0) | 2025.07.11 |
[디자인 패턴] (GoF 행위패턴) Mediator Pattern에 대하여 (0) | 2025.07.10 |
[디자인 패턴] (GoF 행위패턴) Chain of Responsibility Pattern에 대하여 (0) | 2025.07.10 |