프로그래밍👩🏻💻/디자인 패턴
[디자인 패턴] 반복자 패턴(Iterator Pattern)
suyeonme
2022. 8. 9. 09:50
헤드 퍼스트 디자인 패턴을 읽고 정리한 내용입니다.
반복자 패턴이란?
반복자 패턴은 컬렉션의 구현 방법을 노출하지 않으면서 집합체 내의 모든 항목에 접근하는 방법을 제공한다. 반복자 패턴은 Iterator 인터페이스에 의존한다.
* 컬렉션(collection)은 집합체(aggregate)라고도 불리운다.
* java.util.Iterator는 Iterator 인터페이스를 제공한다.
반복자 패턴 사용시 이점
- 컬렉션 객체 안에 들어있는 모든 항목에 접근하는 방식이 통일되어있으면 종류에 관계없이 모든 집합체에 사용할 수 있는 다형적인 코드를 만들 수 있다.
- 모든 항목에 일일히 접근하는 작업을 컬렉션 객체가 아닌 반복자 객체가 맡는다. 따라서 집합체의 인터페이스와 구현이 간단해지고 집합체는 반복작업이 아닌 자신의 일에 집중할 수 있다.
반복자 패턴 예제
MenuItem 클래스
public class MenuItem {
String name;
String description;
boolean vegitarian;
double price;
public MenuItem(String name, String description, boolean vegitarian, double price) {
this.name = name;
this.description = description;
this.vegitarian = vegitarian;
this.price = price;
}
String getName() {
return name;
}
String getDescription() {
return description;
}
String getPrice() {
return price;
}
boolean isVegitarian() {
return vegitarian;
}
}
DinnerMenu 클래스
각각 다른 컬렉션을 사용하여 메뉴를 저장하지만 컬렉션의 종류와 상관없이 반복자를 구현한다.
- Array에는 iterator() 메소드가 존재하지 않으므로 따로 반복자를 구현해야한다.
- ArrayList, HashMap등의 컬렉션 객체는 iterator 메소드를 사용하면 된다.
public class DinerMenu implements Menu {
static final int MAX_ITEMS = 6;
int numberOfItems = 0;
MenuItem[] menuItems; // Array 사용
// ...
public Iterator createIterator() { // (*)
return new DinerMenuIterator(menuItems);
}
}
public class PancakeHouseMenu implements Menu {
List<MenuItem> menuItems; // ArrayList 사용
// ...
public Iterator<MenuItem> createIterator() { // (*)
return menuItems.iterator();
}
}
public class CafeMenu implements Menu {
Map<String, MenuItem> menuItems = new HashMap<String, MenuItem>(); // HashMap 사용
// ...
public Iterator<MenuItem> createIterator() { // (*)
return menuItems.values().iterator();
}
}
DinnerMenuIterator 클래스
public interface Iterator {
boolean hasNext();
MenuItem next();
}
public class DinerMenuIterator implements Iterator {
MenuItem[] items;
int position = 0;
public DinerMenuIterator(MenuItem[] items) {
this.items = items;
}
public MenuItem next() {
MenuItem menuItem = items[position];
position = position + 1;
return menuItem;
}
public boolean hasNext() {
if(position >= items.length || items[position] == null) {
return false;
} else {
return true;
}
}
}
종업원 코드
import java.util.Iterator;
public class Waitress {
List<Menu> menus;
public Waitress(List<Menu> menus) {
this.menus = menus;
}
public void printMenu() {
Iterator<Menu> menuIterator = menus.iterator();
while(menuIterator.hasNext()) {
Menu menu = menuIterator.next();
printMenu(menu.createIterator());
}
}
public void printMenu(Iterator iterator) {
while(iterator.hasNext()) {
MenuItem menuItem = iterator.next();
System.out.print(menuItem.getName());
}
}
}
public class MenuTestDrive {
public static void main(String args[]) {
PancakeHouseMenu pancakeHouseMenu = new PancakeHouseMenu();
DinerMenu dinerMenu = new DinerMenu();
CafeMenu cafeMenu = new CafeMenu();
List<Menu> menus = new ArrayList<Menu>();
menus.add(pancakeHouseMenu);
menus.add(dinerMenu);
menus.add(cafeMenu);
Waitress waitress = new Waitress(menus);
waitress.printMenu();
}
}