《Head-First-设计模式》笔记12-迭代器模式
定义
迭代器模式提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的表示。
把游走的任务放在迭代器上,而不是聚合上,这样简化了聚合的接口和实现,也让责任各得其所。
类图
- Iterator:定义访问和遍历元素的接口
- Concretelterator:具体迭代器,实现迭代器接口,对该聚合遍历时跟踪当前位置。
- Aggregate:聚合,定义创建相应迭代器对象的接口。
- ConcreteAggregate:具体聚合,其工作是实现相应迭代器的接口,返回具体迭代器的一个适当的实例。
问题引入
餐厅和煎饼屋要合并,要把煎饼屋的菜单作为早餐菜单,餐厅的菜单作为午餐菜单。
但是对于菜单项的记录,前者用的是 ArrayList,后者用的是数组,两者都不愿意改变代码实现。
所以在女招待处理的时候,需要用不同的方法分别处理这两个菜单,毕竟菜单项的返回值一个是 ArrayList,一个是数组,遍历的时候也要分别遍历。
实例代码
菜单项
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 Menu {
Iterator createIterator();
}
餐厅(数组)
使用数据聚合 MenuItem
public class DinerMenu implements Menu {
static final int MAX_ITEMS = 6;
int numberOfItems = 0;
MenuItem[] menuItems;
public DinerMenu() {
menuItems = new MenuItem[MAX_ITEMS];
addItem("11", "11", true, 1.11);
addItem("22", "22", true, 1.22);
addItem("33", "33", false, 1.33);
addItem("44", "44", false, 1.44);
}
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("menu full!");
} else {
menuItems[numberOfItems] = menuItem;
numberOfItems++;
}
}
public MenuItem[] getMenuItems() {
return menuItems;
}
@Override
public Iterator createIterator() {
return new DinerMenuIterator(menuItems);
}
}
煎饼屋(List)
public class PancakeHouseMenu implements Menu {
ArrayList menuItems;
public PancakeHouseMenu() {
menuItems = new ArrayList();
addItem("1", "1", true, 1.1);
addItem("2", "2", true, 1.2);
addItem("3", "3", false, 1.3);
addItem("4", "4", false, 1.4);
}
@Override
public Iterator createIterator() {
return menuItems.iterator(); // List 提供了迭代器
}
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 class DinerMenuIterator implements Iterator {
MenuItem[] items;
int position = 0;
public DinerMenuIterator(MenuItem[] items) {
this.items = items;
}
@Override
public boolean hasNext() {
if (position >= items.length || items[position] == null) {
return false;
}
return true;
}
@Override
public Object next() {
MenuItem menuItem = items[position];
position++;
return menuItem;
}
@Override
public void remove() {
if (position <= 0) {
throw new IllegalStateException("null");
}
if (items[position - 1] == null) {
for (int i = position - 1; i < (items.length - 1); i++) {
items[i] = items[i + 1];
}
items[items.length - 1] = null;
}
}
}
服务员
服务员遍历菜单实现解耦。
public class Waitress {
Menu pancakeHouseMenu;
Menu dinerMenu;
public Waitress(Menu pancakeHouseMenu, Menu dinerMenu) {
this.pancakeHouseMenu = pancakeHouseMenu;
this.dinerMenu = dinerMenu;
}
public void printMenu() {
Iterator pancekeIterator = pancakeHouseMenu.createIterator();
Iterator dinerIterator = dinerMenu.createIterator();
printMenu(pancekeIterator);
printMenu(dinerIterator);
}
public void printMenu(Iterator iterator) {
while (iterator.hasNext()) {
MenuItem menuItem = (MenuItem) iterator.next();
System.out.println(menuItem.getName() + "," + menuItem.getDescription() + "," + menuItem.getPrice());
}
}
public static void main(String[] args) {
Menu pMenu = new PancakeHouseMenu();
Menu dMenu = new DinerMenu();
Waitress waitress = new Waitress(pMenu, dMenu);
waitress.printMenu();
}
}
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 bin07280@qq.com
文章标题:《Head-First-设计模式》笔记12-迭代器模式
文章字数:789
本文作者:Bin
发布时间:2018-07-14, 22:07:15
最后更新:2019-08-06, 00:07:35
原始链接:http://coolview.github.io/2018/07/14/Head-First-%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/%E3%80%8AHead-First-%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E3%80%8B%E7%AC%94%E8%AE%B012-%E8%BF%AD%E4%BB%A3%E5%99%A8%E6%A8%A1%E5%BC%8F/版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。