디자인패턴 Iteratoer Pattern

이터레이터 패턴은 컬렉션 구현 방법을 노출시키지 않으면서도 그 집합체 안에 들어있는 모든 항목에 접근할 수 있게 해주는 방법을 제공해 줍니다.

 

Iteratoer Pattern 어떻게 구현할까요?


이터레이터 패턴은 Iterator라는 인터페이스에 의존합니다.
이터레이터 패턴은 이용하면 내부적인 구현 방법을 외부로 노출시키지 않으면서도 집합체에 있는 모든 항목에 일일이 접근할 수 있습니다.
또한 각 항목에 일일이 접근할 수 있게 해주는 기능을 집합체가 아닌 반복자 객체에서 책임지게 된다는 것도 장점으로 작용합니다.
그러면 집합체 인터페이스 및 구현이 간단해지고, 각자 중요한 일만 처리하면 됩니다.

hasNext와 next라는 함수만 노출시킵니다.
이 함수를 사용하는 사용자는 hasNext가 boolean으로 되어있으니 다음 데이터가 있는지 여부를 반환하는 함수라고 예측 가능하고, Next는 MenuItem이라는 객체를 반환하니 객체에 담겨있는 다음 데이터를 보여주는구나라고 예측할 수 있습니다.
하지만 내부적인 구현 방법은 모릅니다.
이렇게 구현 방법을 외부로 노출시키지 않고 기능을 제공할 수 있습니다.

 

구현

Iterator

package cg.park.designpattern.iterator;

public interface Iterator {
   boolean hasNext();
   MenuItem next();
}

 

WashMenuIterator

package cg.park.designpattern.iterator;

public class WashMenuIterator implements Iterator {
    MenuItem[] items;
    int position = 0;

    public WashMenuIterator(MenuItem[] items) {this.items = items;}

    public MenuItem next() {return items[position++];}
    public boolean hasNext() {return items.length > position;}

}

 

Menu

package cg.park.designpattern.iterator;

public interface Menu {
   public Iterator createIterator();
}

 

WashMenu

package cg.park.designpattern.iterator;

public class WashMenu implements Menu {
    static final int MAX_ITEMS = 6;
    int numberOfItems = 0;
    MenuItem[] menuItems;

    public WashMenu() {
        menuItems = new MenuItem[MAX_ITEMS];
        addItem("카 샴푸");
        addItem("세차용 스폰지");
        addItem("휠 브러시 사용");
        addItem("물통에 스폰지 세척");
        addItem("고압수 뿌리기");
        addItem("타월을 이용하여 물기 제거");
    }

    public void addItem(String description) {
        MenuItem washItem = new MenuItem(description);
        if (numberOfItems >= MAX_ITEMS) {
            System.out.println("최대 개수를 초과했습니다.");
            return;
        }
        menuItems[numberOfItems] = washItem;
        numberOfItems++;
    }

    public MenuItem[] getMenuItems() {
        return menuItems;
    }

    public Iterator createIterator() {
        return new WashMenuIterator(menuItems);
    }

}

 

MenuItem

package cg.park.designpattern.iterator;

public class MenuItem {
    String description;
    public MenuItem(String description) {
        this.description = description;
    }
    public String getDescription() {
        return description;
    }
    public String toString() { return description; }
}

 

Cleaner

package cg.park.designpattern.iterator;

public class Cleaner {
    Menu washMenu;

    public Cleaner(Menu washMenu) {
        this.washMenu = washMenu;
    }

    public void cleaning() {
        System.out.println("==========청소 시작==========");
        printCleaning(washMenu.createIterator());
        System.out.println("==========청소 끝==========");
    }

    private void printCleaning(Iterator iterator) {
        while (iterator.hasNext()) {
            MenuItem menuItem = iterator.next();
            System.out.println(menuItem.description);
        }
    }
}

 

IteratorTest

package cg.park.designpattern.iterator;

public class IteratorTest {
    public static void main(String[] args) {
        Cleaner cleaner = new Cleaner(new WashMenu());
        cleaner.cleaning();
    }
}

 

후기

내부적인 구현 방법을 외부로 노출시키지 않으면서도 집합체에 있는 모든 항목에 일일이 접근할 수 있는 방법은 유용한 기술입니다.

Git: https://github.com/qkrcksrbs8/designpattern

참조 자료: Head First Design Patterns

+ Recent posts