深入浅出设计模式-010:迭代器模式(Iterator Pattern)
一:餐厅举例 //菜单项 class MenuItem{ private String name; private String description; private Boolean vegetarian; private 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{ get { return name; } } public String getDescription{ get { return description; } } public Boolean getVegetatian{ get { return vegetarian; } } public Double getPrice{ get { return price; } } } //用ArrayList class PancakeHouseMenu{ private ArrayList menuItems; public PancakeHouseMenu(){ menuItems = new ArrayList(); addItem("11", "11", true, 2); } public void addItem(String name, String description, Boolean vegetarian, Double price){ menuItems.Add(new MenuItem(name, description, vegetarian, price)); } public ArrayList getMenuItems{ get { return menuItems; } } } //用数组 class DinerMenu{ public const int MAX_ITEMS = 6; int numberOfItems = 0; MenuItem[] menuItems; public DinerMenu(){ menuItems = new MenuItem[MAX_ITEMS]; addItem("21", "21", false, 2); } public void addItem(String name, String description, Boolean vegetarian, Double price){ if (numberOfItems < MAX_ITEMS - 1){ menuItems[numberOfItems++] = new MenuItem(name, description, vegetarian, price); } } public MenuItem[] getMenuItems{ get { return menuItems; } } } //遍历时 static void Main(string[] args) { PancakeHouseMenu pancakeHouseMenu = new PancakeHouseMenu(); ArrayList breakfastItems = pancakeHouseMenu.getMenuItems;
DinerMenu dinerMenu = new DinerMenu(); MenuItem[] lunchItems = dinerMenu.getMenuItems;
for (int index = 0; index < breakfastItems.Count; index++) { MenuItem menuItem = (MenuItem)breakfastItems[index]; } for (int index = 0; index < lunchItems.Length; index++) { MenuItem menuItem = lunchItems[index]; } }
二:我们希望的结果是:利用迭代器操作,屏蔽内部细节 static void Main(string[] args) { PancakeHouseMenu pancakeHouseMenu = new PancakeHouseMenu(); DinerMenu dinerMenu = new DinerMenu();
Iterator iterator1 = pancakeHouseMenu.createIterator(); while (iterator1.hasNext()) { MenuItem menuItem = (MenuItem)iterator1.next(); } Iterator iterator2 = dinerMenu.createIterator(); while (iterator2.hasNext()) { MenuItem menuItem = (MenuItem)iterator2.next(); } }
public interface Iterator{ Boolean hasNext(); Object next(); } class DinerMenuIterator : 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; } return true; } public Object next(){ return items[position++]; } } class PancakeHouseMenuIterator : Iterator{ private ArrayList items; int position = 0; public PancakeHouseMenuIterator(ArrayList items){ this.items = items; } public Boolean hasNext(){ if (position >= items.Count || items[position] == null){ return false; } return true; } public Object next(){ return items[position++]; } } class MenuItem{ private String name; private String description; private Boolean vegetarian; private 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{ get { return name; } } public String getDescription{ get { return description; } } public Boolean getVegetatian{ get { return vegetarian; } } public Double getPrice{ get { return price; } } }
class PancakeHouseMenu{ private ArrayList menuItems; public PancakeHouseMenu(){ menuItems = new ArrayList(); addItem("11", "11", true, 2); } public void addItem(String name, String description, Boolean vegetarian, Double price){ menuItems.Add(new MenuItem(name, description, vegetarian, price)); } //关键部分 public Iterator createIterator(){ return new PancakeHouseMenuIterator(menuItems); } } class DinerMenu{ public const int MAX_ITEMS = 6; int numberOfItems = 0; MenuItem[] menuItems; public DinerMenu(){ menuItems = new MenuItem[MAX_ITEMS]; addItem("21", "21", false, 2); } public void addItem(String name, String description, Boolean vegetarian, Double price){ if (numberOfItems < MAX_ITEMS - 1){ menuItems[numberOfItems++] = new MenuItem(name, description, vegetarian, price); } } //关键部分 public Iterator createIterator(){ return new DinerMenuIterator(menuItems); } }
三:迭代器模式:提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的表示。 迭代器模式把元素之间游走的责任交给迭代器,而不是聚合对象。这样不仅让聚合的接口和实现变得更简洁,也可以让聚合更专注在它所应该专注的事情上面,而不必去理会遍历的事情。
四:设计原则:单一责任:一个类应该只有一个引起变化的原因。 类的每个责任都由改变的潜在区域。超过一个责任,就意味着超过一个改变的区域。 当一个模块或一个类被设计成只支持一组相关的功能时,我们说它具有高内聚。