본문 바로가기
카테고리 없음

Iterator Pattern

by 최고영회 2013. 12. 21.
728x90
반응형
SMALL

"순서대로 지정해서 처리하기"

(무엇인가 많이 모여있는 것들을 순서대로 지정하면서 전체를 검색하는 처리를 실행하기 위한 것)

 

배열 arr 의 모든 요소를 표시하기 위해서는

for (int i=0; i<arr.length; i+) {

  System.out.println(arr[i]);

}

로 처리 한다. 변수 i 는 0 으로 초기화 되어 1 씩 증가 한다.

여기에서 사용되고 있는 변수 i 의 기능을 추상화해서 일반화한 것을 디자인 패턴에서 Iterator 패턴 이라고 한다.

 

예제 프로그램)

 

public interface Aggregate {

public abstract Iterator iterator();

}

 

public interface Iterator {

public abstract boolean hasNext();

public abstract Object next();

}

 

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

public class BookShelf implements Aggregate{
private Book[] book;
private int last = 0;
public BookShelf(int maxSize){
this.book = new Book[maxSize];
}
public Book getBook(int index){
return book[index];
}
public void appendBook(Book book){
this.book[last] = book;
last++;
}
public int getLength(){
return last;
}

@Override
public Iterator iterator() {
return new BookShelfIterator(this);
}
}

public class BookShelfIterator implements Iterator{
private BookShelf bookShelf;
private int index;
public BookShelfIterator(BookShelf bookShelf){
this.bookShelf = bookShelf;
}
@Override
public boolean hasNext() {
if(index < bookShelf.getLength()) return true;
else return false;
}

@Override
public Object next() {
Book book = bookShelf.getBook(index);
index++;
return book;
}
}

 public class Main {

public static void main(String[] args) {
BookShelf bookShelf = new BookShelf(4);
bookShelf.appendBook(new Book("Java Design Pattern"));
bookShelf.appendBook(new Book("Bible"));
bookShelf.appendBook(new Book("Thingking of Java"));
bookShelf.appendBook(new Book("Around the world in 80 days"));
Iterator it = bookShelf.iterator();
while(it.hasNext()){
Book book = (Book)it.next();
System.out.println(book.getName());
}
}
}

배열이라면 for 문을 이용해서 돌리면 편한데 왜 집합체의 외부에 Iterator 역할 같은 것을 만들어야 할까?

while(it.hasNext()){

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

 

여기에서 사용되고 있는 것은 hasNext 와 next 라는 iterator의 메소드뿐이다.

BookShelf 의 구현에서 사용되고있는 메소드는 호출되고 있지 않다. 결국 위 코드는 BookShelf 구현에 의존적이지 않다.

BookShelf 를 구현한 사람이 book 을 배열을 이용하지 않고 java.util.List를 사용하도록 프로그램을 수정할 경우에도 위의 while 안의 소스를

변경하지 않아도 동작한다.

java.util.List를 이용해서 BookShelf 를 구현해 보자.

 public class BookShelf implements Aggregate{

private List<Book> bookList;

public BookShelf(){

bookList = new ArrayList<Book>();

}

public Book getBook(int index){

return bookList.get(index);

}

public void appendBook(Book book){

bookList.add(book);

}

public int getLength(){

return bookList.size();

}

@Override

public Iterator iterator() {

return new BookShelfIterator(this);

}

}

 

테스트용 Main Class의 첫번째 줄을  BookShelf bookShelf = new BookShelf();  로 변경하여 테스트 가능 하다.

 

추상클래스나 인터페이스의 사용법을 잘 모르면 Aggregate Interface나 Iterator interface를 사용하지 않고 구현하기 쉽다.

모든 문제를 구체적인 클래스만으로 해결하고자 하는 욕심이 앞서기 때문이다.

그러나 구체적인 클래스만 사용하면 클래스 간의 결합이 강해져 재이용하는 일이 어렵다.

 

결합을 약하게 해서 부품으로 재이용하기 쉽도록 하기 위해 추상클래스나 인터페이스가 도입된다.

 

추상 클래스나 인터페이스를 사용해 프로그래밍을 한다는 사고방식을 반드시 기억하자.

 

Iteraotr pattern 에서 next 란?  "현재 요소를 반환하면서 다음 위치로 진행"

 

관련 패턴

- Visitor Pattern

- Composite Pattern

- Factory Method Pattern

728x90
반응형
LIST