《Head-First-设计模式》笔记12-迭代器模式

  1. 定义
  2. 类图
  3. 问题引入
  4. 实例代码
    1. 菜单项
    2. 共同接口
    3. 餐厅(数组)
    4. 煎饼屋(List)
    5. 餐厅菜单迭代器
    6. 服务员

定义

迭代器模式提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的表示。

把游走的任务放在迭代器上,而不是聚合上,这样简化了聚合的接口和实现,也让责任各得其所。

类图

  • 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" 转载请保留原文链接及作者。

目录