设计模式(十七)行为型:迭代器模式详解

设计模式(十七)行为型:迭代器模式详解

迭代器模式(Iterator Pattern)是 GoF 23 种设计模式中的行为型模式之一,其核心价值在于提供一种统一的方式遍历聚合对象(如集合、容器)中的元素,而无需暴露其内部表示结构 。它将遍历算法从聚合对象中分离出来,封装在独立的迭代器对象中,实现了"单一职责原则"和"开闭原则"。迭代器模式是现代编程语言集合框架的基石,广泛应用于各种数据结构(列表、树、图、哈希表)的遍历操作,是实现 for-each 循环、流式处理(Stream)、延迟计算、外部迭代等机制的核心支撑,是构建可复用、可扩展、高内聚低耦合系统的必备设计模式。

一、详细介绍

迭代器模式解决的是"客户端需要访问聚合对象中的所有元素,但又不希望依赖其内部实现细节"的问题。在传统设计中,聚合类(如 ListTree)通常提供 get(i)elements() 等方法让客户端直接访问内部数据,这导致:

  • 客户端代码与聚合的内部结构(数组、链表、树)紧耦合;
  • 聚合类职责过重,既管理数据又提供遍历逻辑;
  • 难以支持多种遍历方式(如正序、逆序、深度优先、广度优先);
  • 并发修改时难以保证遍历的安全性。

迭代器模式通过引入一个独立的迭代器对象(Iterator) 来封装遍历过程。客户端通过迭代器提供的统一接口(如 hasNext()next())访问元素,而无需关心底层是数组、链表还是树。聚合对象(Aggregate)负责创建并返回一个合适的迭代器实例。

该模式包含以下核心角色:

  • Iterator(迭代器接口) :定义遍历聚合对象所需的操作,通常包括:
    • hasNext():判断是否还有下一个元素。
    • next():返回当前元素并将游标移至下一个。
    • remove()(可选):移除当前元素(Java 中常见)。
  • ConcreteIterator(具体迭代器) :实现 Iterator 接口,针对特定聚合结构(如数组、链表)实现具体的遍历逻辑。它持有对聚合对象的引用或内部状态(如索引、当前节点)。
  • Aggregate(聚合接口) :定义创建迭代器的方法,通常为 createIterator()
  • ConcreteAggregate(具体聚合类) :实现 Aggregate 接口,返回一个与自身结构匹配的 ConcreteIterator 实例。
  • Client(客户端):通过聚合对象获取迭代器,并使用迭代器接口遍历元素。

迭代器模式的关键优势:

  • 解耦聚合与遍历:客户端不依赖聚合的内部结构。
  • 支持多种遍历方式:同一聚合可提供多种迭代器(如正序、逆序、过滤迭代器)。
  • 简化客户端代码:提供统一的遍历接口。
  • 支持并发安全遍历 :迭代器可实现"快照"或"失败快速"机制(如 Java 的 ConcurrentModificationException)。
  • 支持延迟计算(Lazy Evaluation) :元素可在 next() 调用时动态生成(如数据库游标、无限序列)。

与"访问者模式"相比,迭代器关注线性访问元素 ,访问者关注在不修改类的前提下为对象结构添加新操作 ;与"生成器模式"相比,生成器用于创建复杂对象 ,迭代器用于访问已有对象集合

迭代器可分为:

  • 外部迭代器(External Iterator) :客户端主动控制遍历过程(如 while(it.hasNext()))。
  • 内部迭代器(Internal Iterator) :由聚合或迭代器内部控制遍历,客户端提供回调(如 Java 8 的 forEach(Consumer)),更接近"函数式编程"。

二、迭代器模式的UML表示

以下是迭代器模式的标准 UML 类图:
implements implements has a gets iterator uses for traversal <<interface>> Iterator +hasNext() +next() +remove() ConcreteIterator -aggregate: ConcreteAggregate -currentIndex: int +hasNext() +next() +remove() <<interface>> Aggregate +createIterator() ConcreteAggregate -items: List<Object> +createIterator() Client +main(args: String[])

图解说明

  • Iterator 定义统一遍历接口。
  • ConcreteIterator 针对 ConcreteAggregate 实现具体遍历逻辑。
  • ConcreteAggregate 实现 createIterator() 返回其对应的迭代器。
  • Client 通过聚合获取迭代器并遍历。

三、一个简单的Java程序实例及其UML图

以下是一个自定义的 BookShelf 聚合类,使用迭代器模式遍历书架上的书籍。

Java 程序实例
java 复制代码
import java.util.ArrayList;
import java.util.List;

// 书籍类
class Book {
    private String title;
    private String author;

    public Book(String title, String author) {
        this.title = title;
        this.author = author;
    }

    // Getter 方法
    public String getTitle() { return title; }
    public String getAuthor() { return author; }

    @Override
    public String toString() {
        return "\"" + title + "\" by " + author;
    }
}

// 迭代器接口
interface Iterator<T> {
    boolean hasNext();
    T next();
}

// 聚合接口
interface Aggregate<T> {
    Iterator<T> createIterator();
}

// 具体聚合类:书架
class BookShelf implements Aggregate<Book> {
    private List<Book> books = new ArrayList<>();

    public void addBook(Book book) {
        books.add(book);
    }

    public int getSize() {
        return books.size();
    }

    public Book getBookAt(int index) {
        return books.get(index);
    }

    // 实现创建迭代器
    @Override
    public Iterator<Book> createIterator() {
        return new BookShelfIterator(this);
    }
}

// 具体迭代器:书架迭代器
class BookShelfIterator implements Iterator<Book> {
    private BookShelf bookShelf;
    private int currentIndex = 0;

    public BookShelfIterator(BookShelf bookShelf) {
        this.bookShelf = bookShelf;
    }

    @Override
    public boolean hasNext() {
        return currentIndex < bookShelf.getSize();
    }

    @Override
    public Book next() {
        if (!hasNext()) {
            throw new java.util.NoSuchElementException();
        }
        Book book = bookShelf.getBookAt(currentIndex);
        currentIndex++;
        return book;
    }
}

// 客户端使用示例
public class IteratorPatternDemo {
    public static void main(String[] args) {
        System.out.println("📚 书架管理系统 - 迭代器模式示例\n");

        // 创建书架并添加书籍
        BookShelf bookShelf = new BookShelf();
        bookShelf.addBook(new Book("设计模式", "GoF"));
        bookShelf.addBook(new Book("重构", "Martin Fowler"));
        bookShelf.addBook(new Book("代码大全", "Steve McConnell"));

        // 获取迭代器
        Iterator<Book> iterator = bookShelf.createIterator();

        System.out.println("📖 正在遍历书架中的书籍:");
        while (iterator.hasNext()) {
            Book book = iterator.next();
            System.out.println("  ➡️ " + book);
        }

        System.out.println("\n✅ 遍历完成!");

        // 演示:可轻松替换为其他迭代器(如逆序)
        // 若实现 ReverseBookShelfIterator,只需替换 createIterator() 返回即可
        System.out.println("\n💡 说明:客户端代码无需修改即可支持不同遍历方式。");
        System.out.println("🔧 迭代器封装了遍历细节,书架内部可改为链表、树等结构。");
    }
}
实例对应的UML图(简化版)

implements implements has a creates gets iterator uses for traversal Book -title: String -author: String +getTitle() +getAuthor() <<interface>> Iterator<T> +hasNext() +next() <<interface>> Aggregate<T> +createIterator() BookShelf -books: List<Book> +addBook(book: Book) +getSize() +getBookAt(index: int) +createIterator() BookShelfIterator -bookShelf: BookShelf -currentIndex: int +hasNext() +next() Client +main(args: String[])

运行说明

  • BookShelf 是具体聚合类,内部使用 List<Book> 存储书籍。
  • BookShelfIterator 是具体迭代器,持有对 BookShelf 的引用和当前索引。
  • 客户端通过 createIterator() 获取迭代器,使用 hasNext()next() 安全遍历,无需知道 BookShelf 使用 List 实现。

四、总结

特性 说明
核心目的 统一访问聚合元素,隐藏内部结构
实现机制 迭代器对象封装遍历状态与逻辑
优点 解耦、支持多遍历方式、简化客户端、支持延迟计算
缺点 增加类数量、可能增加内存开销(迭代器对象)
适用场景 集合遍历、树/图遍历、数据库游标、流处理、外部API数据访问
不适用场景 遍历逻辑极其简单、性能极度敏感(少量元素)

迭代器模式使用建议

  • Java 集合框架(Collection/Iterator)是迭代器模式的标准实现。
  • 可实现只读迭代器可移除迭代器过滤迭代器转换迭代器等变体。
  • 支持泛型以提高类型安全。
  • 注意并发修改问题,可实现"快照迭代器"或"失败快速"机制。

架构师洞见:

迭代器模式是"关注点分离"与"接口抽象"的典范。在现代架构中,其思想已演变为流式编程(Stream API)响应式编程(Reactive Streams)数据管道 的核心。例如,Java 8 的 Stream 是迭代器的高级抽象,支持链式操作(filter, map, reduce);在大数据处理中,Iterator 是处理海量数据流的基础(如 Hadoop RecordReader);在微服务中,分页 API 的 nextPageToken 本质是分布式迭代器;在前端框架中,虚拟列表(Virtual List)使用迭代器思想按需渲染。

未来趋势是:迭代器将与函数式编程 深度融合,支持更复杂的组合操作;在AI 数据处理 中,数据集迭代器(如 PyTorch DataLoader)是训练模型的关键;在边缘计算 中,迭代器可实现低内存的流式数据处理;在量子计算中,状态叠加的遍历可能需要新型迭代器。

掌握迭代器模式,有助于设计出高内聚、低耦合、可复用 的集合组件。作为架构师,应在设计任何容器类或数据访问层时,主动考虑使用迭代器。迭代器不仅是模式,更是数据访问的哲学 ------它告诉我们:真正的抽象,不在于隐藏数据,而在于提供一种安全、统一、可组合的方式来消费数据,让使用者专注于"做什么",而非"如何做"。

相关推荐
蝸牛ちゃん2 小时前
设计模式(二十二)行为型:策略模式详解
设计模式·系统架构·软考高级·策略模式
蝸牛ちゃん4 小时前
设计模式(六)创建型:单例模式详解
单例模式·设计模式·系统架构·软考高级
易元8 小时前
设计模式-访问者模式
前端·后端·设计模式
IT小白架构师之路9 小时前
常用设计模式系列(十五)—解释器模式
设计模式·解释器模式
蝸牛ちゃん9 小时前
设计模式(二十三)行为型:模板方法模式详解
设计模式·系统架构·软考高级·模板方法模式
蝸牛ちゃん9 小时前
设计模式(十五)行为型:命令模式详解
设计模式·系统架构·软考高级·命令模式
aiguangyuan1 天前
前端开发 Vue 组件优化
系统架构·vue·前端开发
程序员JerrySUN1 天前
Linux系统架构核心全景详解
linux·运维·系统架构
蝸牛ちゃん1 天前
设计模式(七)结构型:适配器模式详解
设计模式·系统架构·软考高级·适配器模式