听说对象村餐厅和对象村煎饼屋合并了,但是好像出现了一点小问题。
因为他们的数据存储类型不同,所以要遍历他们的时候,循环就需要多次,如果再加入一些新的东西,又要改变代码,这会显得很麻烦,怎么办呢,想必大家都只要有一个东西叫做迭代器吧。
让我们手动写一个迭代器接口看看吧。
MenuItem类:
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 boolean isVegetarian() { return vegetarian; } public double getPrice() { return price; } }
迭代器接口:
public interface Iterator { boolean hasNext(); Objects next(); }实现一个具体迭代器:
public class DinerMenuIterator implements Iterator { MenuItem[] items; int position = 0; public DinerMenuIterator(MenuItem[] items) { this.items = items; } public Object next() { MenuItem menuItem = items[position]; position = position + 1; return menuItem; } public boolean hasNext() { if (position >= items.length || items[position] == null) { return false; } else { return true; } } }DinerMenu类: public class DinerMenu { static final int MAX_ITEMS = 6; int numberOfItems = 0; MenuItem[] menuItems; public Iterator createIterator () { return new DinerMenuIterator(menuItems); } }这样以来,一个简单的迭代器的例子就写好了,想必大家都有一个想法:我记得JAVA里明明有自己的迭代器接口啊,为什么要自己写,是不是傻。
对,JAVA是有自带的迭代器,但是我们自己写一个更能明白迭代器到底是怎么一回事,接下来我们就看看JAVA自带的迭代器是怎样的吧。
createIterator类:
public interface createIterator { return menuItems.iterator(); //不创建自己的迭代器,用ArrayList的iterator方法 }DinerMenuIterator类:
import java.util.IllegalFormatCodePointException; import java.util.Iterator; public class DinerMenuIterator implements Iterable { 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("............"); } 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; } } } Menu类:
public interface Menu { public Iterable createIterator(); //这是一个简单接口,让客户能够取得一个菜单项迭代器 }Waitress类:
import java.util.Iterator; 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); } public void printMenu(Iterator iterator) { while (iterator.hasNext()) { MenuItem menuItem = (MenuItem)iterator.next(); System.out.println(menuItem.getName() + ","); System.out.println(menuItem.getPrice() + " --"); System.out.println(menuItem.getDescription()); } } } 以上就是利用JAVA自带的迭代器完成的例子。
迭代器模式:提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的表示。
把游走的任务放在迭代器上,而不是聚合上。这样简化了聚合的接口和实现,也让责任各得其所。
迭代器类图:
最后我们加入一个设计原则---------------单一原则
一个类应该只有一个引起变化的原因。
类的每个责任都有改变潜在区域。超过一个责任,意味着超过一个改变的区域。
总结:
1:迭代器允许访问聚合的元素,而不需要暴露它的内部结构。
2:迭代器将遍历聚合工作封装在一个对象中。
3:当使用迭代器的时候,我们依赖聚合提供遍历。
4:迭代器提供一个通用的接口,让我们遍历聚合的项,当我们编码使用聚合项目时,就可以使用多态机制了。
5:我们应该努力让一个类只分配一个责任。
