디자인 패턴

Iterator Pattern

kyoulho 2024. 5. 27. 22:04

반복자 패턴(Iterator Pattern)은 컬렉션(리스트, 배열 등)의 내부 표현을 노출하지 않고, 요소에 하나씩 접근할 수 있도록 하는 디자인 패턴이다. 또한 각 항목에 일일이 접근할 수 있게 해주는 기능을 집합체가 아닌 반복자 객체가 책임진다는 장점도 있다. 그러면 집합체 인터페이스와 구현이 간단해지고, 각자에게 중요한 일만을 처리할 수 있게 된다.

 

반복자 패턴의 구성 요소

  1. Iterator (반복자):
    • 집합 객체를 순회하면서 각 요소에 접근하는 인터페이스를 정의한다.
    • 요소에 접근하고 순회를 관리하기 위한 메서드들을 포함한다.
  2. ConcreteIterator (구체적인 반복자):
    • Iterator 인터페이스를 구현하여 실제 순회 동작을 구현한다.
    • 현재 위치를 추적하고 다음 요소로 이동하는 등의 기능을 제공한다.
  3. Aggregate (집합 객체):
    • 객체들의 집합을 나타내는 인터페이스를 정의한다.
    • 반복자를 생성하는 메소드를 포함한다.
  4. ConcreteAggregate (구체적인 집합 객체):
    • Aggregate 인터페이스를 구현하여 실제 집합 객체를 생성한다.
    • 구체적인 요소들을 포함하고, 해당 요소들에 대한 반복자를 생성하는 메서드를 제공한다.

 

예제

자바에서 이 패턴은 java.util.Iterator 인터페이스로 구현된다.

public class MenuItem {
    private final String name;
    private final String description;
    private final boolean vegetarian;
    private final double price;

    public MenuItem(String name, String description, boolean vegetarian, double price) {
        this.name = name;
        this.description = description;
        this.vegetarian = vegetarian;
        this.price = price;
    }

    @Override
    public String toString() {
        return "MenuItem{" +
                "name='" + name + '\'' +
                ", description='" + description + '\'' +
                ", vegetarian=" + vegetarian +
                ", price=" + price +
                '}';
    }
}

public interface Menu {
    Iterator<MenuItem> createIterator();
}

public class CafeMenu implements Menu {
    private final Map<String, MenuItem> menuItems = new HashMap<>();

    public CafeMenu() {
    }

    public void addItem(String name, String description, boolean vegetarian, double price) {
        MenuItem menuItem = new MenuItem(name, description, vegetarian, price);
        menuItems.put(name, menuItem);
    }

    /*
        전체 메뉴를 공개하지 않는다.
        내부의 구체적인 구조를 노출하지 않고, 인터페이스를 통해 간접적인 접근을 제공함으로
        최소 지식의 원칙을 지켜야 한다.
     */
    @Deprecated
    public Map<String, MenuItem> getMenuItems() {
        return menuItems;
    }

    @Override
    public Iterator<MenuItem> createIterator() {
        return menuItems.values().iterator();
    }
}

public class DinnerMenu implements Menu {
    private final List<MenuItem> menuItems = new ArrayList<>();

    public DinnerMenu() {
    }

    public void addItem(String name, String description, boolean vegetarian, double price) {
        MenuItem menuItem = new MenuItem(name, description, vegetarian, price);
        menuItems.add(menuItem);
    }

    /*
        전체 메뉴를 공개하지 않는다.
        내부의 구체적인 구조를 노출하지 않고, 인터페이스를 통해 간접적인 접근을 제공함으로
        최소 지식의 원칙을 지켜야 한다.
     */
    @Deprecated
    public List<MenuItem> getMenuItems() {
        return menuItems;
    }

    @Override
    public Iterator<MenuItem> createIterator() {
        return menuItems.iterator();
    }
}

public class Witness {
    private final List<Menu> menus;

    public Witness(CafeMenu cafeMenu, DinnerMenu dinnerMenu) {
        menus = new ArrayList<>();
        menus.add(cafeMenu);
        menus.add(dinnerMenu);
    }

    public void printMenu() {
        for (Menu menu : menus) {
            menu.createIterator().forEachRemaining(System.out::println);
        }
    }
}

'디자인 패턴' 카테고리의 다른 글

Observer Pattern  (0) 2024.05.30
Mediator Pattern  (0) 2024.05.28
Flyweight Pattern  (0) 2024.05.25
Factory Pattern  (0) 2024.05.18
Facade Pattern  (0) 2024.05.12