Intro::
디자인 패턴 중 행위 패턴인 이터레이터에 대해 알아봅시다.
이터레이터 패턴이란?
이터레이터 패턴은 컬렉션(집합체)의 구현 방법을 노출시키지 않으면서, 그 요소들에 순차적으로 접근할 수 있는 방법을 제공하는 디자인 패턴입니다. 이 패턴을 사용하면 컬렉션의 내부 구조와 상관없이 일관된 방식으로 요소들을 탐색할 수 있습니다.
구성 요소
1.
Iterator(이터레이터): 요소들을 순회하는 인터페이스를 정의합니다. 일반적으로 hasNext(), next(), remove() 등의 메소드를 제공합니다.
2.
ConcreteIterator(구체적인 이터레이터): Iterator 인터페이스를 구현하는 클래스로, 컬렉션의 요소를 순회하는 로직을 구현합니다.
3.
Aggregate(집합체): Iterator 객체를 생성하는 인터페이스를 정의합니다.
4.
ConcreteAggregate(구체적인 집합체): Aggregate 인터페이스를 구현하고, ConcreteIterator의 인스턴스를 생성합니다.
장점
•
컬렉션의 구현과 데이터의 순회를 분리하여, 컬렉션의 구현 변경이 이터레이터 사용에 영향을 미치지 않습니다.
•
다양한 종류의 컬렉션에 대해 일관된 순회 방법을 제공합니다.
•
여러 이터레이터를 동시에 사용할 수 있어, 동일한 컬렉션에 대해 다양한 순회 연산을 동시에 수행할 수 있습니다.
단점
•
단순한 컬렉션에 대해서는 오히려 과도한 추상화와 복잡성을 추가할 수 있습니다.
•
이터레이터가 컬렉션의 변경 사항을 적절히 반영하지 못하는 경우(예를 들어, 순회 중에 컬렉션이 변경될 경우) 오류가 발생할 수 있습니다.
코드 예시
import java.util.ArrayList;
import java.util.List;
// Aggregate 인터페이스
interface BookCollection {
BookIterator createIterator();
}
// ConcreteAggregate 클래스
class BookList implements BookCollection {
private List<String> books;
public BookList() {
this.books = new ArrayList<>();
}
public void addBook(String book) {
books.add(book);
}
@Override
public BookIterator createIterator() {
return new BookListIterator(this.books);
}
}
// Iterator 인터페이스
interface BookIterator {
boolean hasNext();
String next();
}
// ConcreteIterator 클래스
class BookListIterator implements BookIterator {
private List<String> books;
private int position = 0;
public BookListIterator(List<String> books) {
this.books = books;
}
@Override
public boolean hasNext() {
return position < books.size();
}
@Override
public String next() {
if (hasNext()) {
return books.get(position++);
}
throw new RuntimeException("No more books in the list.");
}
}
// 사용 예
public class Main {
public static void main(String[] args) {
BookList bookList = new BookList();
bookList.addBook("Book 1");
bookList.addBook("Book 2");
bookList.addBook("Book 3");
BookIterator iterator = bookList.createIterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
}
Java
복사