迭代模式——聚合对象的迭代访问


Demo 地址: https://github.com/ooblee/HelloDesignPattern

1. 定义

迭代器模式(Iterator Pattern):提供一种方法来访问聚合对象,而不用暴露这个对象的内部表示,其别名为游标(Cursor)。迭代器模式是一种对象行为型模式。

聚合对象两大重要职责:

  • 存储数据。
  • 遍历数据。

可以使用迭代器来进行数据的遍历。迭代器提供统一的接口来访问对象。

Java 的集合基本都实现了迭代器。

2. 设计

主要角色:

  • 抽象迭代器(Iterator),定义访问和遍历聚合对象的方法。
  • 具体迭代器(Concrete Iterator),实现抽象迭代器,完成聚合对象的遍历。内部会有游标来记录当前的元素位置。
  • 抽象聚合类(Aggregate),定义创建抽象迭代器的方法。进行聚合对象元素的存储和管理。
  • 具体聚合类(Concrete Aggregate),实现抽象迭代器。

类图:

迭代模式-类图

3. 应用

使用场景:

  • 隐藏内部实现,使用迭代器进行遍历,可以不用关心聚合对象的内部组织关系和数据存储方式。
  • 多种遍历方式,可以增加不同的迭代器,来达到一个聚合对象的多种迭代方式。
  • 统一接口,不同的聚合对象,有统一的方式进行迭代,简化遍历。

现实应用中,我们直接使用各个语言自己实现的迭代器就好了。不需要重复造轮子。

3.1. java.util.Iterator

JDK1.8 的抽象迭代器 Iterator 定义如下:

public interface Iterator<E> {

    boolean hasNext();

    E next();

    default void remove() {
        throw new UnsupportedOperationException("remove");
    }
    
    default void forEachRemaining(Consumer<? super E> action) {
        Objects.requireNonNull(action);
        while (hasNext())
            action.accept(next());
    }
}

各个方法的作用:

  • hasNext,是否有下一个元素
  • next,返回下一个元素
  • remove,删除元素
  • forEachRemaining,使用 Lambda 的风格,函数式调用,进行元素的迭代处理。

使用方式:

public class TestIterator {

    public static void main(String[] args) {

        List<String> list = new ArrayList<>();
        list.add("hello.");
        list.add("hi.");
        list.add("你好.");
        list.add("hola.");

        // 普通方式迭代
        Iterator<String> iterator = list.iterator();
        while (iterator.hasNext()) {
            String content = iterator.next();
            System.out.println(content);
        }

        // Lambada 风格
        iterator = list.iterator();
        iterator.forEachRemaining(System.out::println);
    }

}

4. 特点

4.1. 优势

  • 易修改,如果需要更换遍历算法,更换相应的具体迭代器,对客户端的代码不用修改。
  • 易扩展,可以很方便地新增聚合对象和迭代器。
  • 简化聚合对象,聚合对象不需要单独提供数据遍历的方法。

4.2. 缺点

  • 复杂性增加,每种聚合对象需要单独实现迭代器,会导致迭代器数量膨胀。
  • 设计复杂,迭代器的设计需要考虑到未来的变化,尽可能地思考全面。否则修改抽象实现会影响到所有实现类。
发布了61 篇原创文章 · 获赞 43 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/firefile/article/details/90314344