设计模式(十六)迭代器模式 Iterator

  • 何时须要用到迭代器模式?

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

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

  怎么作?ide

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

  并且针对不一样的集合,咱们须要用不一样的方式去遍历它,这须要去深刻了解各类数据结构,对客户端很不友好。spa

 

  这时候,咱们但愿建立一种超集合(super collection),是客户端可以使用统一的方法去遍历集合,同时不须要关心具体的数据结构。code

  这就是迭代器模式。对象

 

  • 迭代器模式:

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

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

 

  • 模拟场景:

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

  有一个肉食商店(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. 客户端采用统一的方式去遍历数据。
相关文章
相关标签/搜索