반복자 패턴(Iterator Pattern)은 컬렉션(리스트, 배열 등)의 내부 표현을 노출하지 않고, 요소에 하나씩 접근할 수 있도록 하는 디자인 패턴이다. 또한 각 항목에 일일이 접근할 수 있게 해주는 기능을 집합체가 아닌 반복자 객체가 책임진다는 장점도 있다. 그러면 집합체 인터페이스와 구현이 간단해지고, 각자에게 중요한 일만을 처리할 수 있게 된다.
반복자 패턴의 구성 요소
- Iterator (반복자):
- 집합 객체를 순회하면서 각 요소에 접근하는 인터페이스를 정의한다.
- 요소에 접근하고 순회를 관리하기 위한 메서드들을 포함한다.
- ConcreteIterator (구체적인 반복자):
- Iterator 인터페이스를 구현하여 실제 순회 동작을 구현한다.
- 현재 위치를 추적하고 다음 요소로 이동하는 등의 기능을 제공한다.
- Aggregate (집합 객체):
- 객체들의 집합을 나타내는 인터페이스를 정의한다.
- 반복자를 생성하는 메소드를 포함한다.
- 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);
}
}
}
728x90
'디자인 패턴' 카테고리의 다른 글
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 |