Iterator 패턴
- 일련의 데이터 집합에 대하여 순차적인 접근을 지원하는 패턴
- for문에서 사용되는 변수 `i`의 기능을 추상화하여 일반화한 것
- iterator를 '반복자'라고도 한다.
for(int i=0; i<arr.length; i++) {
System.out.println(i);
}
Iterator 패턴 예제
- 책장에 책을 넣고, 책 이름을 차례대로 표시하는 프로그램
- `Iterable<E>` 집합체를 나타내는 인터페이스
- `Iterator<E>` 처리를 반복하는 반복자를 나타내는 인터페이스
- `Book` 책 클래스
- `BookShelf` 책장 클래스
- `BookShelfIterator` 책장 검색 클래스
- `Main` 동작 테스트용 클래스
Iterable<E> 인터페이스
package Iterator;
// Iterator를 만들기 위한 것
// iterator() 메서드를 사용해 Iterator() 인터페이스를 구현한 클래스의 인스턴스를 하나 만든다.
public interface Iterable<E> {
public abstract Iterator<E> iterator();
}
Iterator<E> 인터페이스
package Iterator;
// 하나하나의 요소 처리를 반복하기 위한 것
// 루프 변수와 같은 역할
public interface Iterator<E> {
public abstract boolean hasNext();
public abstract E next();
}
Book 클래스
package Iterator;
public class Book {
private String name;
public Book(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
BookShelf 클래스
package Iterator;
public class BookShelf implements Iterable<Book> {
private Book[] books;
private int last = 0;
public BookShelf(int maxSize) {
this.books = new Book[maxSize];
}
public Book getBookAt(int index) {
return books[index];
}
public void appendBook(Book book) {
this.books[last] = book;
last++;
}
public int getLength() {
return last;
}
@Override
public Iterator<Book> iterator() {
return new BookShelfIterator(this);
}
}
BookShelfIterator 클래스
package Iterator;
import java.util.NoSuchElementException;
public class BookShelfIterator implements Iterator<Book> {
private BookShelf bookShelf;
private int index;
public BookShelfIterator(BookShelf bookShelf) {
this.bookShelf = bookShelf;
this.index = 0;
}
@Override
public boolean hasNext() {
// 다음 책이 있는가?
if(index < bookShelf.getLength()) {
return true;
} else {
return false;
}
}
public Book next() {
if(!hasNext()) {
// 다음 책이 없으면 예외 처리
throw new NoSuchElementException();
}
// 현재 위치의 책 리턴
Book book = bookShelf.getBookAt(index);
// 다음 위치의 책 가리키도록
index++;
return book;
}
}
Main 클래스
`확장 for문을 사용하고 싶었지만 foreach를 iterator에 사용할 수 없다는 에러가 발생하여 우선 주석 처리해두었다.`
package Iterator;
public class Main {
public static void main(String[] args) {
BookShelf bookShelf = new BookShelf(5);
bookShelf.appendBook(new Book("핵심 데이터 모델링"));
bookShelf.appendBook(new Book("친절한 SQL 튜닝"));
bookShelf.appendBook(new Book("디자인 패턴 입문"));
bookShelf.appendBook(new Book("이펙티브 자바"));
bookShelf.appendBook(new Book("자료구조의 이해"));
// 명시적으로 iterator 사용
Iterator<Book> it = bookShelf.iterator();
while (it.hasNext()) {
Book book = it.next();
System.out.println(book.getName());
}
System.out.println();
// 확장 for문 사용
// for(Book book : bookShelf) {
// System.out.println(book.getName());
// }
// System.out.println();
}
}
Iterator 패턴 등장인물
Iterator(반복자)
- 요소를 순서대로 검색하는 인터페이스 결정
- 위 예제에서는 Iterator<E> 인터페이스에 해당한다.
Concretelterator(구체적인 반복자)
- Iterator가 결정한 인터페이스를 실제로 구현
- 검색에 필요한 정보를 가지고 있어야 한다.
- 위 예제에서는 BookShelfIterator 클래스에 해당한다.
Aggregate(집합체)
- Iterator를 만들어 내는 인터페이스 결정
- '내가 가진 요소를 차례로 검색해 주는 사람'을 만들어 내는 메서드
- 위 예제에서는 Iterable<E> 인터페이스에 해당한다.
ConcreteAggregate(구체적인 집합체)
- Aggregate가 결정한 인터페이스를 실제로 구현
- 구체적인 Iterator 역할, 즉 ConcreteIterator의 인스턴스를 만든다.
- 위 예제에서는 BookShelf 클래스에 해당한다.
'Design' 카테고리의 다른 글
디자인패턴 :: Singleton Pattern (0) | 2024.07.08 |
---|---|
디자인패턴 :: Factory Method Pattern (0) | 2024.07.08 |
디자인패턴 :: Template Method Pattern (0) | 2024.07.05 |