Iterator 패턴은 여러가지 요소가 있을때 이를 순서대로 가리키며 전체를 검색하고 처리를 반복 하는 패턴입니다. iterate 라는 뜻은 반복하다 라는 뜻이며 따라서 Iterator 는 반복자 라고도 합니다.
아래는 java 클래스 들입니다.
Book
public class Book {
private String name;
public Book(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
생성자로 Book의 이름을 정의하고 name을 받아오는 메서드를 만들었습니다.
Iterable
public interface Iterable<E> {
public abstract Iterator<E> iterator();
}
interface로 확장할수있도록 하고 제너릭으로 표현했습니다. 여기선 Book 이 사용됩니다. iterator을 추상화 합니다.
Iterator
public interface Iterator<E> {
public abstract E next();
public abstract boolean hasNext();
}
interface로 확장할 수 있도록 하고 동일하게 제너릭을 사용했습니다.
실질적인 반복 임무를 수행하며 hasNext를 통해 있는지 없는지 검증합니다.
BookShelf
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;
}
public Book[] getBooks() {
return books;
}
@Override
public Iterator<Book> iterator() {
return new BookShelfIterator(this);
}
}
Book을 배열로 모으고 Iterable을 implements 하여 구현했습니다.
BookShelfIterator
public class BookShelfIterator implements Iterator<Book> {
private BookShelf bookShelf;
private int index;
public BookShelfIterator(BookShelf bookShelf) {
this.bookShelf = bookShelf;
this.index = 0;
}
@Override
public Book next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
Book book = bookShelf.getBookAt(index);
index++;
return book;
}
@Override
public boolean hasNext() {
if (index < bookShelf.getLength()) {
return true;
} else {
return false;
}
}
}
실질적인 반복 임무가 수행되며 hasNext로 true false 값을 return하여 더 반복할지 체크합니다.
Main
BookShelf bookShelf = new BookShelf(4);
bookShelf.appendBook(new Book("Around the World in 80 Days"));
bookShelf.appendBook(new Book("Bible"));
bookShelf.appendBook(new Book("Cinderella"));
bookShelf.appendBook(new Book("Daddy"));
Iterator<Book> it = bookShelf.iterator();
while (it.hasNext()) {
Book book = it.next();
System.out.println(book.getName());
}
System.out.println();
for (Book b :
bookShelf.getBooks()) {
System.out.println(b.getName());
}
foreach와 Iterator패턴의 비교입니다.
출력 결과
foreach문과 결과가 동일한것을 알 수 있습니다. 근데 왜 불편하게 Iterator 패턴이라는게 있는걸까요??
생각해보면 유지보수성을 향상시킨다는 것을 알 수 있습니다.
하지만 추상클래스 와 인터페이스 등 사용하기 번거로운것도 사실입니다. 잘 고려해서 사용해야 할 것 같습니다.