zoukankan      html  css  js  c++  java
  • 设计模式(十六)迭代器模式 Iterator

    • 什么时候需要用到迭代器模式?

      有许多中方法,可以把对象堆起来放进一个集合(可以是数组、堆栈、列表、哈希表,等等)。

      每一种类型的集合,都有各自适用的时机。但是某个时间段,客户端可能希望去遍历这个集合。

      怎么做?

      让客户去得到这个集合的具体实现?显然这不是很现实。

      而且针对不同的集合,我们需要用不同的方式去遍历它,这需要去深入了解各种数据结构,对客户端很不友好。

      这时候,我们希望创建一种超集合(super collection),是客户端能够使用统一的方法去遍历集合,同时不需要关心具体的数据结构。

      这就是迭代器模式。

    • 迭代器模式:

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

      从 Java 的角度来说,迭代器模式就是 Iterator 接口。

    • 模拟场景:

      有一个水果商店(FruitShop),内部采取数组的方式存储数据。

      有一个肉食商店(MeatShop),内部采用链表的方式存储数据。

      客户端希望去遍历这些数据,

    • 没有迭代器的实现:
    public final class FruitShop {
    
        private String[] products = new String[MAX_PRODUCT];
        private int index = 0;
    
        private static final int MAX_PRODUCT = 10;
    
        public void addProduct(String product) {
            if (index < MAX_PRODUCT) {
                products[index++] = product;
            } else {
                throw new RuntimeException("FruitShop is full");
            }
        }
    
        public String[] getProducts() {
            return Arrays.copyOf(products, index);
        }
    }
    public final class MeatShop {
    
        private List<String> products = new LinkedList<>();
    
        public void addProduct(String product) {
            products.add(product);
        }
    
        public List<String> getProducts() {
            return products;
        }
    }
        @Test
        void testFruitShop() {
            FruitShop fruitShop = new FruitShop();
            fruitShop.addProduct("Apple");
            fruitShop.addProduct("Orange");
            String[] products = fruitShop.getProducts();
            for (String product : products) {
                System.out.println(product);
            }
        }
    
        @Test
        void testMeatShop() {
            MeatShop meatShop = new MeatShop();
            meatShop.addProduct("Beef");
            meatShop.addProduct("Pork");
            List<String> products = meatShop.getProducts();
            for (String product : products) {
                System.out.println(product);
            }
        }

      上面的代码有如下的问题:

    1. 两个 Shop 暴露了内部的数据结构。
    2. 客户端采取不同的方法去遍历数据。
    • 包含迭代器的实现
    public final class FruitShopIterator implements Iterator<String> {
    
        private String[] products = new String[MAX_PRODUCT];
        private int index = 0;
    
        private int iteratorIndex = 0;
    
        private static final int MAX_PRODUCT = 10;
    
        public void addProduct(String product) {
            if (index < MAX_PRODUCT) {
                products[index++] = product;
            } else {
                throw new RuntimeException("FruitShop is full");
            }
        }
    
        @Override
        public boolean hasNext() {
            return iteratorIndex < index;
        }
    
        @Override
        public String next() {
            return products[iteratorIndex++];
        }
    }
    public final class MeatShopIterator implements Iterator<String> {
    
        private List<String> products = new LinkedList<>();
        private int iteratorIndex = 0;
    
        public void addProduct(String product) {
            products.add(product);
        }
    
        @Override
        public boolean hasNext() {
            return iteratorIndex < products.size();
        }
    
        @Override
        public String next() {
            return products.get(iteratorIndex++);
        }
    }
        @Test
        void testFruitShopIterator() {
            FruitShopIterator fruitShop = new FruitShopIterator();
            fruitShop.addProduct("Apple");
            fruitShop.addProduct("Orange");
            while (fruitShop.hasNext()) {
                System.out.println(fruitShop.next());
            }
        }
    
        @Test
        void testMeatShopIterator() {
            MeatShopIterator meatShop = new MeatShopIterator();
            meatShop.addProduct("Beef");
            meatShop.addProduct("Pork");
            while (meatShop.hasNext()) {
                System.out.println(meatShop.next());
            }
        }

      可以看出:

    1. Iterator 提供了 hasNext() 和 next() 方法负责集合数据的遍历。
    2. Shop 类避免了暴露具体的数据结构。
    3. 客户端采用统一的方式去遍历数据。
  • 相关阅读:
    PS软件之,快速的修改图片你的尺寸
    想的太多,做的太少
    Java-Junit 的Hello world
    Java-hibernate的映射文件
    工作思路
    Spring入门Hello World
    PHP 进制问题
    Java-hibernate的Hello World
    PHP获得header头进行分析
    动软模板使用教程
  • 原文地址:https://www.cnblogs.com/jing-an-feng-shao/p/10842137.html
Copyright © 2011-2022 走看看