美文网首页
理解迭代器模式

理解迭代器模式

作者: 梦的飞翔_862e | 来源:发表于2018-11-30 15:04 被阅读0次
    概念理解

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

    实例讲解

    蛋糕店和中餐厅都有自己的菜单,蛋糕店使用数组存储自己的菜单列表,中餐厅使用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

    相关文章

      网友评论

          本文标题:理解迭代器模式

          本文链接:https://www.haomeiwen.com/subject/gwoccqtx.html