《HeadFirst设计模式》读书笔记-第9章-迭代器模式
来源:互联网 发布:淘宝情趣珍珠内裤评论 编辑:程序博客网 时间:2024/06/11 15:16
定义
迭代器模式(iterator pattern)提供一种方法顺序访问一个集合对象中的各个元素,而又不暴露其内部的表示。
迭代器模式把遍历集合内元素的操作交给了迭代器,而集合本身专注在管理元素,这符合单一责任原则,让设计具有高内聚。
代码实现
下面以JDK现有的Iterator的例子来说明适配器模式使用。
给出创建Iterator接口的定义:
import java.util.Iterator;public interface Menu { public Iterator createIterator();}
菜单项的BEAN对象:
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; }}
具体集合对象,管理(增加,移除,查找等)集合的元素,实现创建Iterator接口
import java.util.ArrayList;import java.util.Iterator;public class PancakeHouseMenu implements Menu { ArrayList menuItems; // 内部存储是ArrayList 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}
另一个具体集合对象,内部的存储是数组
import java.util.Iterator;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", "A medly of 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); } // other menu methods here}
数组类型的迭代器的实现:
import java.util.Iterator; // 使用JDK中迭代器接口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; } }}
另一个具体集合对象,内部的存储是Hashtable
import java.util.*;public class CafeMenu implements Menu { Hashtable menuItems = new Hashtable(); //内部的存储是Hashtable public CafeMenu() { addItem("Veggie Burger and Air Fries", "Veggie burger on a whole wheat bun, lettuce, tomato, and fries", true, 3.99); addItem("Soup of the day", "A cup of the soup of the day, with a side salad", false, 3.69); addItem("Burrito", "A large burrito, with whole pinto beans, salsa, guacamole", true, 4.29); } public void addItem(String name, String description, boolean vegetarian, double price) { MenuItem menuItem = new MenuItem(name, description, vegetarian, price); menuItems.put(menuItem.getName(), menuItem); } public Hashtable getItems() { return menuItems; } public Iterator createIterator() { return menuItems.values().iterator(); }}
客户(招待员)代码,她持有Menu接口,通过这个接口去创建迭代器遍历菜单,她不需要知道菜单项内部的存储细节。
import java.util.Iterator;public class Waitress { Menu pancakeHouseMenu; // 煎饼屋菜单 Menu dinerMenu; // 餐厅菜单 Menu cafeMenu; // 咖啡厅菜单 public Waitress(Menu pancakeHouseMenu, Menu dinerMenu, Menu cafeMenu) { this.pancakeHouseMenu = pancakeHouseMenu; this.dinerMenu = dinerMenu; this.cafeMenu = cafeMenu; } public void printMenu() { // 生成迭代器接口 Iterator pancakeIterator = pancakeHouseMenu.createIterator(); Iterator dinerIterator = dinerMenu.createIterator(); Iterator cafeIterator = cafeMenu.createIterator(); System.out.println("MENU\n----\nBREAKFAST"); printMenu(pancakeIterator); System.out.println("\nLUNCH"); printMenu(dinerIterator); System.out.println("\nDINNER"); printMenu(cafeIterator); } // 遍历迭代器,遍历所有迭代器的代码都可以复用这段代码 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---------------"); printVegetarianMenu(pancakeHouseMenu.createIterator()); printVegetarianMenu(dinerMenu.createIterator()); printVegetarianMenu(cafeMenu.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; } Iterator cafeIterator = cafeMenu.createIterator(); if (isVegetarian(name, cafeIterator)) { 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.print(menuItem.getPrice() + " -- "); System.out.println(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; }}
测试驱动代码
import java.util.*;public class MenuTestDrive { public static void main(String args[]) { // Menu pancakeHouseMenu = new PancakeHouseMenu(); Menu dinerMenu = new DinerMenu(); Menu cafeMenu = new CafeMenu(); Waitress waitress = new Waitress(pancakeHouseMenu, dinerMenu, cafeMenu); // 各种遍历菜单的方式 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"); } }}
从上面的代码可以看出,迭代器让客户遍历集合的代码更加通用,它不用关心集合内部的存储细节,因为集合对象创建的迭代器封装了遍历具体数据结构的细节。
本章金句
Java Collection框架里面很多类都实现了Iterator接口,可细研究
集合类把遍历集合内元素的责任封装在Iterator接口,集合只需要专注在管理集合的元素,比如,添加,删除,查找等。让一个类只做一件事,遵守单一责任原则,这样的设计更加容易维护
1 0
- 《HeadFirst设计模式》读书笔记-第9章-迭代器模式
- 《HeadFirst设计模式》读书笔记-第1章-策略模式
- 《HeadFirst设计模式》读书笔记-第2章-观察者模式
- 《HeadFirst设计模式》读书笔记-第4章-工厂模式
- 《HeadFirst设计模式》读书笔记-第5章-单例模式
- 《HeadFirst设计模式》读书笔记-第6章-命令模式
- 《HeadFirst设计模式》读书笔记-第3章-装饰者模式
- 《HeadFirst设计模式》读书笔记-第8章-模板方法模式
- 《HeadFirst设计模式》读书笔记-第7章-外观模式
- 《HeadFirst设计模式》读书笔记-第7章-适配器模式
- HeadFirst设计模式 读书笔记
- HeadFirst设计模式 读书笔记
- 读书笔记:《HeadFirst设计模式》
- HeadFirst设计模式读书笔记
- HeadFirst设计模式 读书笔记1
- HeadFirst设计模式 读书笔记2
- HeadFirst设计模式 读书笔记3
- HeadFirst设计模式 读书笔记4
- 计算机概观--硬件组成
- scala学习过程中的笔记
- 网页处理实践(4)——对selenium做异常处理
- PRML读书笔记——线性分类模型
- 泛型方法
- 《HeadFirst设计模式》读书笔记-第9章-迭代器模式
- nginx could not be resolved (3: Host not found)错误解决方案
- 使用ngrok搭建自己的内网服务
- 【设计模式】——原型模式
- 1011: [HNOI2008]遥远的行星
- nsa
- 用python创建桌面应用(三)
- 【笔记】pom.xml配置参考
- 集合框架