迭代器模式
定义:提供一种方法顺序访问一个聚合对象中各个元素, 而又无须暴露该对象的内部表示。
简单来说,不同种类的对象可能需要不同的遍历方式,我们对每一种类型的对象配一个迭代器,最后多个迭代器合成一个。
主要解决:不同的方式来遍历整个整合对象。
何时使用:遍历一个聚合对象。
优点: 1、它支持以不同的方式遍历一个聚合对象。 2、迭代器简化了聚合类。 3、在同一个聚合上可以有多个遍历。 4、在迭代器模式中,增加新的聚合类和迭代器类都很方便,无须修改原有代码。
缺点:由于迭代器模式将存储数据和遍历数据的职责分离,增加新的聚合类需要对应增加新的迭代器类,类的个数成对增加,这在一定程度上增加了系统的复杂性。
举例(咖啡厅和中餐厅合并,他们两个餐厅的菜单一个是数组保存的,一个是ArrayList保存的。遍历方式不一样,使用迭代器聚合访问,只需要一种方式)
1 迭代器接口
public interface Iterator { public boolean hasNext(); public Object next(); }
2 咖啡店菜单和咖啡店菜单遍历器
public class CakeHouseMenu { private ArrayList<MenuItem> menuItems; public CakeHouseMenu() { menuItems = new ArrayList<MenuItem>(); addItem("KFC Cake Breakfast","boiled eggs&toast&cabbage",true,3.99f); addItem("MDL Cake Breakfast","fried eggs&toast",false,3.59f); addItem("Stawberry Cake","fresh stawberry",true,3.29f); addItem("Regular Cake Breakfast","toast&sausage",true,2.59f); } private void addItem(String name, String description, boolean vegetable, float price) { MenuItem menuItem = new MenuItem(name, description, vegetable, price); menuItems.add(menuItem); } public Iterator getIterator() { return new CakeHouseIterator() ; } class CakeHouseIterator implements Iterator { private int position=0; public CakeHouseIterator() { position=0; } @Override public boolean hasNext() { // TODO Auto-generated method stub if(position<menuItems.size()) { return true; } return false; } @Override public Object next() { // TODO Auto-generated method stub MenuItem menuItem =menuItems.get(position); position++; return menuItem; }}; }
3 中餐厅菜单和中餐厅菜单遍历器
public class DinerMenu { private final static int Max_Items = 5; private int numberOfItems = 0; private MenuItem[] menuItems; public DinerMenu() { menuItems = new MenuItem[Max_Items]; addItem("vegetable Blt", "bacon&lettuce&tomato&cabbage", true, 3.58f); addItem("Blt", "bacon&lettuce&tomato", false, 3.00f); addItem("bean soup", "bean&potato salad", true, 3.28f); addItem("hotdog", "onions&cheese&bread", false, 3.05f); } private void addItem(String name, String description, boolean vegetable, float price) { MenuItem menuItem = new MenuItem(name, description, vegetable, price); if (numberOfItems >= Max_Items) { System.err.println("sorry,menu is full!can not add another item"); } else { menuItems[numberOfItems] = menuItem; numberOfItems++; } } public Iterator getIterator() { return new DinerIterator(); } class DinerIterator implements Iterator { private int position; public DinerIterator() { position = 0; } @Override public boolean hasNext() { // TODO Auto-generated method stub if (position < numberOfItems) { return true; } return false; } @Override public Object next() { // TODO Auto-generated method stub MenuItem menuItem = menuItems[position]; position++; return menuItem; } }; }
4 女服务员
public class Waitress { private ArrayList<Iterator> iterators = new ArrayList<Iterator>(); public Waitress() { } public void addIterator(Iterator iterator) { iterators.add(iterator); } public void printMenu() { Iterator iterator; MenuItem menuItem; for (int i = 0, len = iterators.size(); i < len; i++) { iterator = iterators.get(i); while (iterator.hasNext()) { menuItem = (MenuItem) iterator.next(); System.out .println(menuItem.getName() + "***" + menuItem.getPrice() + "***" + menuItem.getDescription()); } } } public void printBreakfastMenu() { } public void printLunchMenu() { } public void printVegetableMenu() { } }