在上篇文章中,printMenu()的实现的几个问题,在这篇文章中,予以解决。
首先问题的原因是什么?很明显,不同的collection类型,煎饼屋菜单使用的是ArrayList,而餐厅的菜单使用的是数组。
代码的区别如下
- ArrayList 和 数组的元素遍历:
for(int i = 0; i < breakfastItems.size(); i++){ MenuItem item = (MenuItem)breakfastItems.get(i); } for(int i = 0; i < lunchItems.length; i++){ MenuItem item = lunchItems[i]; }
如果我们使用迭代器,上面的代码就变成了:
- 在ArrayList上使用迭代器
//在ArrayList上使用迭代器 Iterator iterator = breakfastItems.createIterator(); while(iterator.hasNext()){ MenuItem menuItem = (MenuItem)iterator.next(); }
- 在数组上使用迭代器
//在数组上使用迭代器 Iterator iterator = lunchMenu.createIterator(); while(iterator.hasNext()){ MenuItem menuItem = (MenuItem)iterator.next(); }
我们可以看到,在数组上和在ArrayList上使用迭代器的代码完全一致。(或许迭代器失去了collection本身的一些特性,比如ArrayList和数组通过下标来存取元素。但是迭代器本身就是为了遍历而存在)。
接下来,使用迭代器模式(Iterator Pattern)来改写代码。
迭代器接口:
package com.hufei.learnDesignPattern.improve; public interface Iterator { boolean hasNext(); Object next(); }
餐厅菜单迭代器:
public class DinerMenuIterator implements Iterator { MenuItem[] items; int position = 0; public DinerMenuIterator(MenuItem[] items){ this.items = items; } public boolean hasNext() { if(position >= items.length || items[position] == null){ return false; }else{ return true; } } public Object next() { MenuItem menuItem = items[position]; position = position + 1; return menuItem; } }
餐厅菜单,什么都不需要修改,只是增加一个createIterator()方法。
//DinerMenu什么都不需要改,只需要增加一个createIterator()方法。 public class DinerMenu { static final int MAX_ITEMS = 6; int numberOfItems = 0; MenuItem[] menuItems; public DinerMenu(){ menuItems = new MenuItem[MAX_ITEMS]; } 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 ; } } //不再需要MenuItems方法 /* public MenuItem[] getMenuItems(){ return this.menuItems; }*/ public Iterator createIterator(){ return new DinerMenuIterator(menuItems); } //还有菜单的其他方法 }
女招待类中,现在只需要一个循环即可。
public class Waitress { PancakeHouseMenu pancakeHouseMenu; DinerMenu dinerMenu; public Waitress(PancakeHouseMenu pancakeHouseMenu, DinerMenu dinerMenu) { super(); this.pancakeHouseMenu = pancakeHouseMenu; this.dinerMenu = dinerMenu; } public void printMenu(){ Iterator pancakeIterator = this.pancakeHouseMenu.createIterator(); Iterator dinerIterator = dinerMenu.createIterator(); System.out.println("MENU/n----/nBREAKFAST"); printMenu(pancakeIterator); System.out.println("MENU/n----/nLUNCH"); printMenu(dinerIterator); } public void printMenu(Iterator it){ while(it.hasNext()){ MenuItem menuItem = (MenuItem)it.next(); System.out.print(menuItem.getName()+", "); System.out.print(menuItem.getPrice()+"-- "); System.out.println(menuItem.getDescription()); } } }