Java设计模式(十):迭代器设计模式
1.应用场景
(1)访问一个聚合对象的内容而无需暴露它的内部表示
(2)支持对聚合对象的多种遍历
(3)为遍历不同的聚合结构提供一个统一的接口
2.概念
提供一种顺序访问聚合对象元素的方法,并且不暴露聚合对象的内部表示。这个模式给使用者提供了一种方法,可以顺序访问一个聚集对象中的元素,而又不用知道内部是如何表示的。
3. Class Digram
- Aggregate 是聚合类,其中 createIterator() 方法可以产生一个 Iterator;
- Iterator 主要定义了 hasNext() 和 next() 方法。
- Client 组合了 Aggregate,为了迭代遍历 Aggregate,也需要组合 Iterator。
4. Implementation
public interface Menu {
public Iterator createIterator();
}
public interface Iterator {
boolean hasNext();
MenuItem next();
}
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 String toString() {
return (name + ", $" + price + "\n " + description);
}
}
public class PancakeHouseMenu implements Menu {
ArrayList<MenuItem> menuItems;
public PancakeHouseMenu() {
menuItems = new ArrayList<MenuItem>();
addItem("K&B's Pancake Breakfast",
"Pancakes with scrambled eggs, and toast",
true,
2.99);
addItem("Regular Pancake Breakfast",
"Pancakes with fried eggs, sausage",
false,
2.99);
addItem("Blueberry Pancakes",
"Pancakes made with fresh blueberries",
true,
3.49);
addItem("Waffles",
"Waffles, with your choice of blueberries or strawberries",
true,
3.59);
}
public void addItem(String name, String description,
boolean vegetarian, double price)
{
MenuItem menuItem = new MenuItem(name, description, vegetarian, price);
menuItems.add(menuItem);
}
public ArrayList<MenuItem> getMenuItems() {
return menuItems;
}
public Iterator createIterator() {
return new PancakeHouseMenuIterator(menuItems);
}
public String toString() {
return "Objectville Pancake House Menu";
}
// other menu methods here
}
public class PancakeHouseMenuIterator implements Iterator {
ArrayList<MenuItem> items;
int position = 0;
public PancakeHouseMenuIterator(ArrayList<MenuItem> items) {
this.items = items;
}
public MenuItem next() {
MenuItem item = items.get(position);
position = position + 1;
return item;
}
public boolean hasNext() {
if (position >= items.size()) {
return false;
} else {
return true;
}
}
}
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",
"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);
// To test Alternating menu items, comment out above line,
// and uncomment the line below.
//return new AlternatingDinerMenuIterator(menuItems);
}
// other menu methods here
}
public class DinerMenuIterator implements Iterator {
private MenuItem[] menuItem;
int position=0;
public DinerMenuIterator(MenuItem[] menuItem) {
this.menuItem = menuItem;
}
@Override
public boolean hasNext() {
return position < menuItem.length && menuItem[position] != null;
}
@Override
public MenuItem next() {
MenuItem menuItem = this.menuItem[position];
position++;
return menuItem;
}
}
public class Waiterss {
PancakeHouseMenu pancakeHouseMenu;
DinerMenu dinerMenu;
public Waiterss(PancakeHouseMenu pancakeHouseMenu, DinerMenu dinerMenu) {
this.pancakeHouseMenu = pancakeHouseMenu;
this.dinerMenu = dinerMenu;
}
public void printMenu() {
Iterator pancakeIterator = pancakeHouseMenu.createIterator();
Iterator dinerIterator = dinerMenu.createIterator();
System.out.println("MENU\n----\nBREAKFAST");
printMenu(pancakeIterator);
System.out.println("\nLUNCH");
printMenu(dinerIterator);
}
private void printMenu(Iterator iterator) {
while (iterator.hasNext()) {
MenuItem menuItem = iterator.next();
System.out.print(menuItem.getName() + ", ");
System.out.print(menuItem.getPrice() + " -- ");
System.out.println(menuItem.getDescription());
}
}
}
public class MenuTestDriver {
public static void main(String[] args) {
DinerMenu dinerMenu=new DinerMenu();
PancakeHouseMenu pancakeHouseMenu=new PancakeHouseMenu();
Waiterss waiterss=new Waiterss(pancakeHouseMenu,dinerMenu);
waiterss.printMenu();
Iterator iterator = pancakeHouseMenu.createIterator();
while (iterator.hasNext()){
MenuItem next = iterator.next();
System.out.println(next);
}
System.out.println();
Iterator dinerMenuIterator = dinerMenu.createIterator();
while (dinerMenuIterator.hasNext()){
MenuItem next = dinerMenuIterator.next();
System.out.println(next);
}
}
}