zoukankan      html  css  js  c++  java
  • 迭代器模式的理解和示例

    一、是什么

    1. 定义: 在对象集合之间游走,而不暴露集合的实现

    二、示例

    代理背景:

      1. 有汉堡包店和晚餐店的菜单, 假设汉堡包店的菜单是用List存放, 晚餐店是用数组存放的(用不同的存放方式,为了体现迭代器统一的处理方式)

      2. 服务生要将两家店的菜单都打印出来 

      3. 这里先自己重写Iterator, 为了体现迭代器的设计模式,在实际使用中,可以直接循环Iterator

    2.1 菜单项 Menu, 菜单有名称和价格

    /**
     * 菜单
     */
    public class Menu {
       private String name;
       private Double price;
    
        public Menu(String name, Double price) {
            this.name = name;
            this.price = price;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public Double getPrice() {
            return price;
        }
    
        public void setPrice(Double price) {
            this.price = price;
        }
    }

    2.2 晚餐店, 注意这里是用数组存放菜单的

    /**
     * 晚餐店
     */
    public class DinnerShop {
    
        private static final int MAX_ITEMS = 4;
        int index = 0;
        Menu[] menuItems;
    
        public DinnerShop() {
            menuItems = new Menu[MAX_ITEMS];
    
            // 默认就放入菜单项
            addItem("浪漫晚餐", 299d);
            addItem("小龙虾", 99d);
            addItem("鱿鱼", 49d);
            addItem("扇贝", 89d);
        }
    
        public void addItem(String name, double price) {
            Menu menu = new Menu(name, price);
            if (index >= MAX_ITEMS) {
                System.err.println("对不起, 菜单页满了");
            } else {
                menuItems[index] = menu;
                index++;
            }
        }
    
        // 创建迭代器:重点
        public Iterator createIteraotr() {
            return new DinnerMenuIterator(menuItems);
        }
    }

    晚餐点菜单迭代器, 重写next()和hasNext()方法

    /**
     * 晚餐菜单遍历类
     */
    public class DinnerMenuIterator implements Iterator {
        Menu[] menuItems;
        int position = 0;
    
        public DinnerMenuIterator(Menu[] menuItems) {
            this.menuItems = menuItems;
        }
    
        @Override
        public boolean hasNext() {
            if (position >= menuItems.length || menuItems[position] == null) {
                return false;
            }
    
            return true;
        }
    
        @Override
        public Object next() {
            Menu menuItem = menuItems[position];
            position++;
            return menuItem;
        }
    }

    2.3 汉堡包店, 这里用List存放菜单

    /**
     * 汉堡店菜单
     */
    public class PancakeHouseShop {
    
        /**
         * 菜单列表
         */
        List<Menu> menuItems;
    
        public PancakeHouseShop() {
            this.menuItems = new ArrayList<>();
    
            // 默认就放入菜单项
            addItem("可乐", 3d);
            addItem("汉堡", 13d);
            addItem("薯条", 8d);
            addItem("鸡翅", 5d);
        }
    
        public void addItem(String name, Double price) {
            Menu menu = new Menu(name, price);
            menuItems.add(menu);
        }
    
        // 产生迭代器
        public Iterator createIterator() {
            return new PancakeHouseMenuIterator(menuItems);
        }
    }

    汉堡包店迭代器

    /**
     * 汉堡包菜单迭代类
     */
    public class PancakeHouseMenuIterator implements Iterator {
        List<Menu> menuItems;
        int position = 0;
    
        public PancakeHouseMenuIterator(List<Menu> menuItems) {
            this.menuItems = menuItems;
        }
    
        @Override
        public boolean hasNext() {
            if (position >= menuItems.size() || menuItems.get(position) == null) {
                return false;
            }
    
            return true;
        }
    
        @Override
        public Object next() {
            Menu menuItem = menuItems.get(position);
            position++;
    
            return menuItem;
        }
    }

    2.4 测试类:服务生

    /**
     * 服务生
     */
    public class Waiter {
    
        public void print() {
            System.out.println("================== 汉堡包菜单 ======================");
            PancakeHouseShop pancakeHouseShop = new PancakeHouseShop();
            Iterator pancakeHouseMenuIterator = pancakeHouseShop.createIterator();
            printMenu(pancakeHouseMenuIterator);
    
            System.out.println("=================== 晚餐菜单 =====================");
            DinnerShop dinnerShop = new DinnerShop();
            Iterator dinnerMenuIterator = dinnerShop.createIteraotr();
            printMenu(dinnerMenuIterator);
        }
    
        private void printMenu(Iterator iterator) {
            while (iterator.hasNext()) {
                Menu menu = (Menu) iterator.next();
                System.out.println("名称: " + menu.getName() + "======== 价格: " + menu.getPrice());
            }
        }
    
        public static void main(String[] args) {
            Waiter waiter = new Waiter();
            waiter.print();
        }
    }

    控制台打印:

    ================== 汉堡包菜单 ======================
    名称: 可乐======== 价格: 3.0
    名称: 汉堡======== 价格: 13.0
    名称: 薯条======== 价格: 8.0
    名称: 鸡翅======== 价格: 5.0
    =================== 晚餐菜单 =====================
    名称: 浪漫晚餐======== 价格: 299.0
    名称: 小龙虾======== 价格: 99.0
    名称: 鱿鱼======== 价格: 49.0
    名称: 扇贝======== 价格: 89.0

    
    

    三、总结

    1. 这里没有用直接将数组和List生成Iterator, 是为了更方便的看出迭代器的作用

    2. 用同一的方式来遍历,不暴露内部细节

  • 相关阅读:
    基于注解的IOC配置
    字符串典型问题分析
    指针与数组
    数组的本质
    数组与指针分析
    指针的本质
    #与##操作符使用
    #pragma使用分析
    #error和#line使用分析
    条件编译使用
  • 原文地址:https://www.cnblogs.com/milicool/p/11278623.html
Copyright © 2011-2022 走看看