Skip to content

이터레이터 패턴 #
Find similar titles

Structured data

Category
Programming

이터레이터 패턴(Iterator Pattern) #

JAVA 언어에서 for문의 i++에서 i를 하나씩 증가시키면서 배열 arr의 요소 전체를 처음부터 차례대로 검색하게 됩니다. 여기서 사용되고 있는 변수 i의 기능을 추상화해서 일반화한 것을 디자인 패턴에서는 Iterator 패턴이라고 합니다.
Iterator패턴이란, 무엇인가 많이 모여있는 것들을 순서대로 지정하면서 전체를 검색하는 처리를 실행하기 위한 것입니다. (Iterator : 반복하다 , 반복자)

Iterator패턴의 등장인물 #

Iterator(반복자)의 역할 #

요소를 순서대로 검색해가는 인터페이스를 결정합니다.
다음 요소가 존재하는지를 얻기위한 hasNext()와 다음 요소를 얻기 위한 next()를 결정합니다.

ConcreateIterator(구체적인 반복자)의 역할 #

Iterator가 결정한 인터페이스를 실제로 구현합니다.
이 역할은 검색하기 위해 필요한 정보를 가지고 있어야 합니다.

Aggregate(집합체)의 역할 #

Iterator역할을 만들어내는 인터페이스를 결정합니다.
이 인터페이스는 '내가 가지고 있는 요소를 순서대로 검색해 주는 사람'을 만들어 내는 메소드 입니다.

ConcreateAggregate(구체적인 집합체)의 역할 #

Aggregate역할이 결정한 인터페이스를 실제로 구현하는 일을 합니다.
구체적인 Iterator 역할, 즉 ConcreteIterator역할의 인스턴스를 만들어 냅니다.

예제 #


1. Aggregate 인터페이스 - 집합체를 나타내는 인터페이스
2. Iterator 인터페이스 - 하나씩 나열하면서 검색을 실행하는 인터페이스
3. Book 클래스 - 책을 나타내는 클래스
4. BookShelf 클래스 - 서가를 나타내는 클래스
5. BookShelfIterator 클래스 - 서가를 검색하는 클래스
6. Main 클래스 - 동작 테스트용 클래스

Aggregate 인터페이스 #

Aggregate인터페이스는 요소들이 나열되어 있는 '집합체'를 나타냅니다.
인터페이스를 구현하고 있는 클래스는 배열과 같이 무엇인가가 많이 모여있습니다.
aggregate는 '모으다','모이다','집합'이라는 의미 입니다.

public interface Aggregate {
    public abstract Iterator iterator();
   }

Aggregate인터페이스에서 선언되어 있는 메소드는 iterator메소드 하나뿐입니다.
이 메소드는 집합체에 대응하는 Iterator를 1개 작성하기 위한 것입니다.
집합체를 하나씩 나열하고, 검색하고, 조사하고 싶을 때에는 iterator 메소드를 사용해서 Iterator인터페이스를 구현한 클래스의 인스턴스를 1개 만듭니다.

Iterator 인터페이스 #

Iterator 인터페이스는 요소를 하나씩 나열하면서 루프 변수와 같은 역할을 수행합니다.

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

'다음 요소'가 존재하는지를 조사하기 위한 HasNext 메소드.
hasNext 메소드의 반환값은 boolean형이고, 다음 요소가 존재하면 true를 반환 다음요소가 존재하지 않으면 false반환.
'다음 요소'를 얻기 위한 next메소드.
next메소드는 반환값이 Object형이고, 집합체의 요소를 1개 반환해 줍니다.
다음 next메소드를 호출했을 때 정확히 다음 요소를 반환하도록 내부 상태를 다음으로 진행시켜 두는 역할도 합니다.

Book 클래스 #

Book 클래스는 책을 나타내는 클래스 입니다.
할수 있는 일은 책 이름을 getName메소드에서 얻는 일뿐입니다.
책 이름은 생성자에서 인스턴스를 초기화할 때 인수로 지정 합니다.

public class Book{
    private String name;
    public Book(String name){
        this.name = name;
    }
    public String getName(){
        return name;
    }
}


BookShelf 클래스 #

BookShelf 클래스는 서가를 나타내는 클래스입니다.
이 클래스를 집합체로 다루기 위해 Aggregate인터페이스를 구현하고 있습니다.
소스 안의 'implements Aggregate'가 Aggregate 인터페이스를 구현하고 있다는 것을 나태냅니다.
또한, Aggreagete인터페이스에서 선언되어 있던 iterator 메소드가 기술되어 있는 것도 확인 할 수 있습니다.

public class BookShelf implements Aggregate{
    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 Iterator iterator(){
        return new BookShelfIterator(this);
    }
}

이 서가는 books라는 필드를 가지고 있습니다. 이필드는 Book의 배열입니다.
이 배열의 크기는 처음에 BookShelf의 인스턴스를 만들 때 지정합니다.
books필드를 private로 한 이유는, 이클래스 외부로부터 뜻하지 않게 변경되는 것을 방지하기 위해서 입니다.
iterator메소드는 BooksShelf클래스에 대앙하는 Iterator로서, BookShelfIterator라는 클래스의 인스턴스를 생성해서 그것을 반환합니다.
이 서가의 책을 하나씩 나열하고 싶을 때는 iterator메서드를 호출합니다.

BookShelfIterator 클래스 #

BookShelf클래스의 검색을 실행하는 BookShelfIterato클래스 이다.

public class BookShelfIterator implements Iterator{
    private BookShelf booShelf;
    private int index;
    public BookShelfIterator(BookShelf bookShelf){
        this.bookShelf=bookshelf;
        this.index = 0;
    }
    public boolean hasNext(){
        if(index<bookShelf.getLength()){
            return true;
        }else{
            return false;
        }
    }
    public Object next(){
        book = bookShelf.getBookAt(index);
        index++;
        return book;
    }
}

BookShelfIterator를 iterator로서 다루기 위해 Iterator인터페이스를 구현하고 있습니다.
bookShelf 필드는 BookShlfIterator가 검색할 서가이고, index 필드는 현재 주목하고 있는 책을 가르키는 첨자입니다.
생성자에서는 전달된 BookShelf의 인스턴스를 bookShlf필드에 저장하고 index를 0으로 합니다.
hasNext메소드는 Iterator인터페이스에서 선언되어 있는 메서드를 구현한 것입니다.
'다음 책'이 있는지를 조사해서 있으면 true, 없으면 false를 반환합니다.
다음 책이 있는지 없는지는 index가 서가에 있는 책을 권수(식 bookShelf.getLength()의 값) 보다 작은지, 큰지로 판정합니다.
next메소드는 현재 처리하고 있는 책(book의 인스턴스)을 반환하고, 다시 '다음'으로 진행시키기 위한 메소드입니다.
Iterator인터페이스에서 선언되어 있는 메소드로써 조금 복잡합니다.
우선 반환값으로 반환해야 할 책을 book이라는 변수로 저장해 두고 index를 다음으로 진행시킵니다.
'index를 다음 으로 진행'시키는 처리는 서두에서 언급한 for문의 i++에 해당하는 처리입니다.
루프변수를 '다음'으로 진행시킨 것 입니다.

Main 클래스 #

이것으로 서가를 검색할 준비가 끝났습니다. 그러면 Main클래스를 이용해서 작은 서가를 만들어 봅니다.

public class Main {
    public static void main(String[] args){
        BookShlf bookShelf = new BookShelf(4);
        bookShelf.appendBook(new Book("Around the World in 80"));
        bookShelf.appendBook(new Book("Bible"));
        bookShelf.appendBook(new Book("Cinderella"));
        bookShelf.appendBook(new Book("Daddy-Long-Legs"));
        Iterator it = bookShelf.iterator();
        while(it.hasNext()){
            Book book = (Book)it.next();
            System.out.println(book.getName());
        }
    }
}
  • 우선 책이 4권이 들어가 있는 서가를 만들고
  • 순서대로 4권의 책을 만들어 넣었습니다.
  • bookShelf.iterator()에 의해 얻어지는 it이 서가를 검색하기 위한 Iterator의 인스턴스 입니다.
  • While의 조건 부분에 쓰는 것은 물론 it.hasNext()입니다. 이것으로 책이 있는 한 while루프가 돌아가고,
  • 루프내에서 it.next()에 의해 책을 한권씩 조사하게 됩니다.

구현에 상관없이 Iterator를 사용할 수 있다. #

  • Iterator패턴을 궂이 사용해야 하는 이유는?
    • iterator를 사용함 으로써 구현과 분리해서 하나씩 셀 수 있기 때문입니다.

      while(it.hasNext()){
          Book book = (Book) it.next();
          System.out.println(book.getName());
      }
      

      여기에서 사용되고 있는 것은 hasNext와 next라는 Iterator의 메소드 뿐입니다.
      BookShelf의 구현에서 사용되고 있는 메소드는 호출되고 있지 않습니다.
      결국 위 코드의 while루프는 BookShelf의 구현에는 의존하지 않습니다.
      BookShlf를 구현할 사람이 배열을 이용해서 책을 관리하는 것을 그만두고,
      java.util.Vector를 사용하도록 프로그램을 수정했다고한다면
      BookShelf을 어떻게 수정하더라도 BookShelf가 iterator메소드를 가지고 있으면서 올바른 Iterator를 반환해 준다면, 위의 While루프는 전혀 변경되지 않아도 동작합니다.

      디자인 패턴은 클래스의 재이용화를 촉진한다.
      재이용화를 촉진하는것은 클래스를 부품처럼 사용할 수 있게 하고,
      하나의 부품을 수정해도 다른 부품에 큰 영향 없이 적은 수정만으로 끝낼 수 있다는 것을 의미합니다.

관련 패턴 #

Visitor패턴 #

많은 것이 모여 있는 내부를 돌아다니면서 같은 처리를 반복 적용해가는 패턴입니다.

Composite패턴 #

Composite패턴은 재귀적인 구조를 갖는 페턴입니다.

Facory Method 패턴 #

iterator메소드가 iterator 인스턴스를 작성할 때 Factory method 패턴이 사용되는 경우 가 있다.

0.0.1_20140628_0