迭代器模式提供了一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的表示。
类图
我们现在使用java.util提供的ArrayList迭代器,所有不需要PancakeHoseMenuIterator这个类了。
(图片源于网络)
代码实现(Java)
// Menu.java public interface Menu { public Iterator createIterator(); }
// PancakeHouseMenu.java public class PancakeHouseMenu implements Menu { ArrayList menuItems; public PancakeHouseMenu() { menuItems = new ArrayList(); 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, and blueberry syrup", 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 getMenuItems() { return menuItems; } public Iterator createIterator() { return menuItems.iterator(); } // other menu methods here }
// DinerMenu.java 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); //return new AlternatingDinerMenuIterator(menuItems); } // other menu methods here }
// MenuItem.java 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; } }
// Waitress.java public class Waitress { Menu pancakeHouseMenu; Menu dinerMenu; public Waitress(Menu pancakeHouseMenu, Menu 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 = (MenuItem)iterator.next(); System.out.print(menuItem.getName() + ", "); System.out.print(menuItem.getPrice() + " -- "); System.out.println(menuItem.getDescription()); } } public void printVegetarianMenu() { System.out.println("\nVEGETARIAN MENU\n----\nBREAKFAST"); printVegetarianMenu(pancakeHouseMenu.createIterator()); System.out.println("\nLUNCH"); printVegetarianMenu(dinerMenu.createIterator()); } public boolean isItemVegetarian(String name) { Iterator pancakeIterator = pancakeHouseMenu.createIterator(); if (isVegetarian(name, pancakeIterator)) { return true; } Iterator dinerIterator = dinerMenu.createIterator(); if (isVegetarian(name, dinerIterator)) { return true; } return false; } private void printVegetarianMenu(Iterator iterator) { while (iterator.hasNext()) { MenuItem menuItem = (MenuItem)iterator.next(); if (menuItem.isVegetarian()) { System.out.print(menuItem.getName()); System.out.println("\t\t" + menuItem.getPrice()); System.out.println("\t" + menuItem.getDescription()); } } } private boolean isVegetarian(String name, Iterator iterator) { while (iterator.hasNext()) { MenuItem menuItem = (MenuItem)iterator.next(); if (menuItem.getName().equals(name)) { if (menuItem.isVegetarian()) { return true; } } } return false; } }
// DinerMenuIterator.java 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; } } }
测试代码
// MenuTestDrive.java public class MenuTestDrive { public static void main(String args[]) { PancakeHouseMenu pancakeHouseMenu = new PancakeHouseMenu(); DinerMenu dinerMenu = new DinerMenu(); Waitress waitress = new Waitress(pancakeHouseMenu, dinerMenu); waitress.printMenu(); waitress.printVegetarianMenu(); System.out.println("\nCustomer asks, is the Hotdog vegetarian?"); System.out.print("Waitress says: "); if (waitress.isItemVegetarian("Hotdog")) { System.out.println("Yes"); } else { System.out.println("No"); } System.out.println("\nCustomer asks, are the Waffles vegetarian?"); System.out.print("Waitress says: "); if (waitress.isItemVegetarian("Waffles")) { System.out.println("Yes"); } else { System.out.println("No"); } } }
运行效果
MENU ---- BREAKFAST K&B's Pancake Breakfast, 2.99 -- Pancakes with scrambled eggs, and toast Regular Pancake Breakfast, 2.99 -- Pancakes with fried eggs, sausage Blueberry Pancakes, 3.49 -- Pancakes made with fresh blueberries, and blueberry syrup Waffles, 3.59 -- Waffles, with your choice of blueberries or strawberries LUNCH Vegetarian BLT, 2.99 -- (Fakin') Bacon with lettuce & tomato on whole wheat BLT, 2.99 -- Bacon with lettuce & tomato on whole wheat Soup of the day, 3.29 -- Soup of the day, with a side of potato salad Hotdog, 3.05 -- A hot dog, with saurkraut, relish, onions, topped with cheese Steamed Veggies and Brown Rice, 3.99 -- Steamed vegetables over brown rice Pasta, 3.89 -- Spaghetti with Marinara Sauce, and a slice of sourdough bread VEGETARIAN MENU ---- BREAKFAST K&B's Pancake Breakfast2.99 Pancakes with scrambled eggs, and toast Blueberry Pancakes3.49 Pancakes made with fresh blueberries, and blueberry syrup Waffles3.59 Waffles, with your choice of blueberries or strawberries LUNCH Vegetarian BLT2.99 (Fakin') Bacon with lettuce & tomato on whole wheat Steamed Veggies and Brown Rice3.99 Steamed vegetables over brown rice Pasta3.89 Spaghetti with Marinara Sauce, and a slice of sourdough bread Customer asks, is the Hotdog vegetarian? Waitress says: No Customer asks, are the Waffles vegetarian? Waitress says: Yes |