반복자 (반복자) 모드 노출 그 내부를 표시하지 않고, 중합체 개체의 각 요소에 대한 순차적 인 방법을 제공한다.
각 개체의 중합에 액세스 균일 한 방법이있는 경우 다형성 코드를 사용하여 이러한 중합을 작성할 수 있습니다. 대신 집계 객체의 반복자의 마이그레이션에 대한 책임의 요소 사이의 반복 모드. 이 인터페이스를보다 간결하게 구현의 집계를 할 수 있습니다, 또한 중합 우리가 (즉, 관리되는 개체의 컬렉션)하지 않고는 일을 무시하고 통과 할에 집중해야한다, 위의 것들에 더 초점을 맞출 수 있습니다뿐만 아니라.
구체적인 예를 참조하여 설명한다.
우리는 지금 우리가 접시 3 개 개의 레스토랑을 지적 할 수 같은 시간에 같은 장소에서 고객을 수 있도록하려면, 레스토랑, 팬케이크 하우스와 카페를 시뮬레이션.
원래 메뉴 구현에서와 레스토랑의 메뉴 数组
기록 된 메뉴 항목, 팬케이크 집 메뉴 ArrayList
기록 된 메뉴 항목, 메뉴와 카페 동안 Hashtable
기록 메뉴 항목.
우리는 메뉴 인터페이스를 추출
import java.util.Iterator;
public interface Menu {
public Iterator createIterator();
}
클래스 메뉴 항목은
public class MenuItem {
String name;
String description;
boolean vegetarian;
double price;
public MenuItem(String name,
String description,
boolean vegetarian,
double price)
{
this.name = name;
this.description = description;
this.vegetarian = vegetarian;
this.price = price;
}
public String getName() {
return name;
}
public String getDescription() {
return description;
}
public double getPrice() {
return price;
}
public boolean isVegetarian() {
return vegetarian;
}
}
우리는 웨이트리스의 자바 버전을 만들 필요가, 그녀는 요리사를 요구하지 않고, 사용자 정의 메뉴를 인쇄, 심지어 메뉴 항목이 채식주의 여부를 알려하는 고객의 필요에 응답 할 수 있어야합니다.
우리는이 레스토랑의 메뉴는 동일한 인터페이스를 달성 할 수있는 방법을 찾을 필요가있다. 언급 한 이전 기사에서 우리는 중요한 설계 원칙은이 변화의 패키지의 일부 . 분명히, 여기에 변경 사항이 발생하는 다른 유형의 집합으로 이송됩니다. 우리는이 문제를 해결하기 위해 반복자 패턴의 도움이 필요합니다.
반복 모드는 인터페이스라는 반복자에 의존
public interface Iterator {
boolean hasNext();
Object next();
}
팬케이크 하우스의 경우 ArrayList
메뉴와 카페 Hashtable
메뉴, 자바는 기본 반복자를 달성하고, 레스토랑의를위한 数组
메뉴, 당신은 우리가 반복자를 소유하고 있음을 깨달을 필요가 :
import java.util.Iterator;
public class DinerMenuIterator implements Iterator {
MenuItem[] list;
int position = 0;
public DinerMenuIterator(MenuItem[] list) {
this.list = list;
}
public Object next() {
MenuItem menuItem = list[position];
position = position + 1;
return menuItem;
}
public boolean hasNext() {
if (position >= list.length || list[position] == null) {
return false;
} else {
return true;
}
}
public void remove() {
if (position <= 0) {
throw new IllegalStateException
("You can't remove an item until you've done at least one next()");
}
if (list[position-1] != null) {
for (int i = position-1; i < (list.length-1); i++) {
list[i] = list[i+1];
}
list[list.length-1] = null;
}
}
}
는 레스토랑 메뉴로서 구현 대응
import java.util.Iterator;
public class DinerMenu implements Menu {
static final int MAX_ITEMS = 6;
int numberOfItems = 0;
MenuItem[] menuItems;
public DinerMenu() {
menuItems = new MenuItem[MAX_ITEMS];
addItem("Vegetarian BLT",
"(Fakin') Bacon with lettuce & tomato on whole wheat", true, 2.99);
addItem("BLT",
"Bacon with lettuce & tomato on whole wheat", false, 2.99);
addItem("Soup of the day",
"Soup of the day, with a side of potato salad", false, 3.29);
addItem("Hotdog",
"A hot dog, with saurkraut, relish, onions, topped with cheese",
false, 3.05);
addItem("Steamed Veggies and Brown Rice",
"A medly of steamed vegetables over brown rice", true, 3.99);
addItem("Pasta",
"Spaghetti with Marinara Sauce, and a slice of sourdough bread",
true, 3.89);
}
public void addItem(String name, String description,
boolean vegetarian, double price)
{
MenuItem menuItem = new MenuItem(name, description, vegetarian, price);
if (numberOfItems >= MAX_ITEMS) {
System.err.println("Sorry, menu is full! Can't add item to menu");
} else {
menuItems[numberOfItems] = menuItem;
numberOfItems = numberOfItems + 1;
}
}
public MenuItem[] getMenuItems() {
return menuItems;
}
public Iterator createIterator() {
return new DinerMenuIterator(menuItems);
//return new AlternatingDinerMenuIterator(menuItems);
}
// other menu methods here
}
디자인 원칙 - 단일 책임 원칙
우리는 우리가 우리가 클래스 (종류 중합의) 자신의 일을 완료 할 수 있습니다뿐만 아니라 그래서, 그 안에서 중합뿐만 아니라 관련 운영 및 순회 방법의 설정을 달성 할 수 있도록하는 경우도 더 많은 책임을 부담하는 동시에 (예를 들어, 탐색), 우리는 이러한 종류의 변화에 대한 두 가지 이유를 주었다 :
- 이 컬렉션이 변경되는 경우,이 클래스는 그것으로 변경해야
- 우리가 변화의 길을 통과하면이 범주도 함께 변경해야합니다
그래서, 우리의 오랜 친구 "변화"다시 한번 우리의 디자인 원칙의 중심이되었다 - 단일 책임 원칙 : 클래스가 변경에 대해 하나의 이유가 될 것이다.