理解迭代器模式

2018-11-30  本文已影响0人  梦的飞翔_862e
概念理解

迭代器模式是非常常见的一种行为模式,它能顺序的访问容器中的元素,不用关心容器的内部存储实现。

实例讲解

蛋糕店和中餐厅都有自己的菜单,蛋糕店使用数组存储自己的菜单列表,中餐厅使用List存储自己的菜单列表,现要将两者合并,打印出一份菜单列表出来。

设计一

这种结构是直观的设计,Waiter类不仅需要依赖两个餐厅,还需要知道两个餐厅的具体实现,这样才能打印出菜单。很明显,这种结构系统内部耦合性太强,不利于扩展。

public class CakeHouse {
    private MenuItem[] menuItems;
    private int count = 0;
    private int maxCount = 10;

    public CakeHouse() {
        menuItems = new MenuItem[maxCount];
    }

    public void addItem(MenuItem menuItem) {
        if (count == maxCount) {
            return;
        }
        menuItems[count++] = menuItem;
    }

    public int getCount() {
        return count;
    }

    public MenuItem[] getMenuItems() {
        return menuItems;
    }

    public void setMenuItems(MenuItem[] menuItems) {
        this.menuItems = menuItems;
    }
}
public class DinnerRestaurant {
    private List<MenuItem> menuItemList;

    public DinnerRestaurant() {
        menuItemList = new ArrayList<MenuItem>();
    }

    public void addItem(MenuItem menuItem) {
        menuItemList.add(menuItem);
    }

    public List<MenuItem> getMenuItemList() {
        return menuItemList;
    }

    public void setMenuItemList(List<MenuItem> menuItemList) {
        this.menuItemList = menuItemList;
    }
}
public class Waiter {
    private CakeHouse house;
    private DinnerRestaurant dinnerRestaurant;

    public Waiter(CakeHouse cakeHouse,DinnerRestaurant restaurant){
        this.house = cakeHouse;
        this.dinnerRestaurant = restaurant;
    }

    public void printAllMenus(){
       MenuItem[] menuItems =  this.house.getMenuItems();
       for(int i =0; i<this.house.getCount();i++){
            System.out.println(menuItems[i]);
        }

        List<MenuItem> menuItemList = this.dinnerRestaurant.getMenuItemList();
       for(int i =0; i<menuItemList.size();i++){
           System.out.println(menuItemList.get(i));
       }
    }
}
设计二:使用迭代器

迭代器非常简单,两个餐厅仅需要提供各自的迭代器即可,Waiter类不需要知道两个餐厅的具体存储菜单的方式,仅需要维护一个可以提供迭代器的容器列表。


public interface Iterator<T> {
    boolean hasNext();
    T next();
}
public interface Container {
    Iterator getIterator();
}
public class CakeHouse implements Container {
    private MenuItem[] menuItems;
    private int count = 0;
    private int maxCount = 10;
    private int currentIndex = 0;
    public CakeHouse() {
        menuItems = new MenuItem[maxCount];
    }
    public void addItem(MenuItem menuItem) {
        if (count == maxCount) {
            return;
        }
        menuItems[count++] = menuItem;
    }
    public int getCount() {
        return count;
    }
    public MenuItem[] getMenuItems() {
        return menuItems;
    }

    public void setMenuItems(MenuItem[] menuItems) {
        this.menuItems = menuItems;
    }

    public Iterator getIterator(){
        return new CakeHouseIterator();
    }

    private class CakeHouseIterator implements Iterator<MenuItem> {

        @Override
        public boolean hasNext() {
            return currentIndex < count;
        }

        @Override
        public MenuItem next() {
            return menuItems[currentIndex++];
        }
    }
}
public class DinnerRestaurant implements Container {
    private List<MenuItem> menuItemList;
    private int currentIndex = 0;

    public DinnerRestaurant() {
        menuItemList = new ArrayList<MenuItem>();
    }

    public void addItem(MenuItem menuItem) {
        menuItemList.add(menuItem);
    }

    public List<MenuItem> getMenuItemList() {
        return menuItemList;
    }

    public void setMenuItemList(List<MenuItem> menuItemList) {
        this.menuItemList = menuItemList;
    }


    public Iterator getIterator(){
        return new DinnerIterator();
    }
    private class DinnerIterator implements Iterator<MenuItem> {

        @Override
        public boolean hasNext() {
            return currentIndex < menuItemList.size();
        }

        @Override
        public MenuItem next() {
            return menuItemList.get(currentIndex++);
        }
    }
}
public class Waiter {
    
    private List<Container> containerList;

    public Waiter() {
       containerList = new ArrayList<Container>();
    }

    public void addContainer(Container container) {
        containerList.add(container);
    }

    public void printMenu() {
        for(int i =0; i< containerList.size();i++){
            Container container = containerList.get(i);
            Iterator iterator =container.getIterator();
            while(iterator.hasNext()){
                System.out.println(iterator.next());
            }
        }
    }
}
总结

jdk中已经存在了迭代器接口Iterator,set,list也实现了迭代器。
迭代器将存储数据和遍历数据的职责分开,增加聚合类仅需提供迭代器,无需修改现有代码。
代码实例参见
https://github.com/jxl198/designPattern/tree/master/iterator

上一篇下一篇

猜你喜欢

热点阅读