【设计模式】【行为型模式】迭代器模式(Iterator)

简介: 一、入门 什么是迭代器模式? 迭代器模式(Iterator Pattern)是一种行为设计模式,它提供了一种顺序访问聚合对象中元素的方法,而不需要暴露其底层表示。迭代器模式将遍历逻辑从聚合对象中分离出

👋hi,我不是一名外包公司的员工,也不会偷吃茶水间的零食,我的梦想是能写高端CRUD

🔥 2025本人正在沉淀中... 博客更新速度++

👍 欢迎点赞、收藏、关注,跟上我的更新节奏

🎵 当你的天空突然下了大雨,那是我在为你炸乌云

一、入门

什么是迭代器模式?

迭代器模式(Iterator Pattern)是一种行为设计模式,它提供了一种顺序访问聚合对象中元素的方法,而不需要暴露其底层表示。迭代器模式将遍历逻辑从聚合对象中分离出来,使得聚合对象可以专注于数据存储,而迭代器负责遍历。

为什么要迭代器模式?

在没有迭代器模式的情况下,客户端代码需要直接依赖书架的内部结构(如数组或列表)来遍历书籍。这种方式会导致遍历逻辑与书架类耦合。

// 书籍类
class Book {
   
    private String name;

    public Book(String name) {
   
        this.name = name;
    }

    public String getName() {
   
        return name;
    }
}

// 书架类
class BookShelf {
   
    private Book[] books;
    private int size;

    public BookShelf(int capacity) {
   
        books = new Book[capacity];
        size = 0;
    }

    public void addBook(Book book) {
   
        if (size < books.length) {
   
            books[size++] = book;
        }
    }

    // 暴露内部数组
    public Book[] getBooks() {
   
        return books;
    }

    // 暴露书架大小
    public int getSize() {
   
        return size;
    }
}

// 客户端代码
public class LibraryWithoutIterator {
   
    public static void main(String[] args) {
   
        BookShelf bookShelf = new BookShelf(3);
        bookShelf.addBook(new Book("Design Patterns"));
        bookShelf.addBook(new Book("Clean Code"));
        bookShelf.addBook(new Book("Refactoring"));

        // 直接依赖书架的内部结构(数组)进行遍历
        Book[] books = bookShelf.getBooks();
        for (int i = 0; i < bookShelf.getSize(); i++) {
   
            System.out.println(books[i].getName());
        }
    }
}

存在的问题

  1. 耦合性强:客户端代码直接依赖书架的内部结构(数组),如果书架的存储结构改为链表,客户端代码也需要修改。
  2. 破坏封装性:书架类暴露了内部数据(数组和大小),客户端代码可以直接操作这些数据,可能导致数据不一致。
  3. 无法统一遍历接口:如果图书馆中有多种存储结构(如书架、电子书库等),客户端代码需要为每种结构编写特定的遍历逻辑。

怎么实现迭代器模式?

迭代器模式的组成

  1. 迭代器接口(Iterator Interface):定义了遍历元素所需的操作,如next()hasNext()等。
  2. 具体迭代器(Concrete Iterator):实现迭代器接口,负责管理当前遍历的位置。
  3. 聚合接口(Aggregate Interface):定义了创建迭代器的方法,如createIterator()
  4. 具体聚合类(Concrete Aggregate):实现聚合接口,返回一个具体迭代器的实例。

【案例】图书管理 - 改

image.png

迭代器接口(Iterator Interface)Iterator迭代器接口,定义遍历聚合对象所需的方法。

interface Iterator<T> {
   
    boolean hasNext();
    T next();
}
具体迭代器(Concrete Iterator):BookShelfIterator 类,实现迭代器接口,负责管理当前遍历的位置,并实现具体的遍历逻辑。
// 具体迭代器
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() {
   
        Book book = bookShelf.getBookAt(currentIndex); // 获取当前元素
        currentIndex++; // 移动游标
        return book;
    }
}

聚合接口(Aggregate Interface): Aggregate接口,定义创建迭代器的方法。

// 聚合接口
interface Aggregate<T> {
   
    Iterator<T> createIterator(); // 创建迭代器
}
具体聚合类(Concrete Aggregate):BookShelf类,实现聚合接口,负责存储和管理数据,并提供创建迭代器的方法。
// 具体聚合类
class BookShelf implements Aggregate<Book> {
   
    private Book[] books; // 存储书籍的数组
    private int size;      // 当前书籍数量

    // 构造函数,初始化书架容量
    public BookShelf(int capacity) {
   
        books = new Book[capacity];
        size = 0;
    }

    // 添加书籍
    public void addBook(Book book) {
   
        if (size < books.length) {
   
            books[size++] = book;
        }
    }

    // 获取指定位置的书籍
    public Book getBookAt(int index) {
   
        return books[index];
    }

    // 获取当前书籍数量
    public int getSize() {
   
        return size;
    }

    // 实现聚合接口,创建迭代器
    @Override
    public Iterator<Book> createIterator() {
   
        return new BookShelfIterator(this); // 将当前书架对象传递给迭代器
    }
}

Book类

class Book {
   
    private String name;

    public Book(String name) {
   
        this.name = name;
    }

    public String getName() {
   
        return name;
    }
}

测试类

// 客户端代码
public class LibraryDemo {
   
    public static void main(String[] args) {
   
        // 创建一个书架
        BookShelf bookShelf = new BookShelf(3);
        bookShelf.addBook(new Book("Design Patterns"));
        bookShelf.addBook(new Book("Clean Code"));
        bookShelf.addBook(new Book("Refactoring"));

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

        // 使用迭代器遍历书架
        System.out.println("Books in BookShelf:");
        while (iterator.hasNext()) {
   
            Book book = iterator.next();
            System.out.println(book.getName());
        }
    }
}

输出结果

Books in BookShelf:
Design Patterns
Clean Code
Refactoring

二、迭代器模式在源码中的运用

Java 集合框架(Java Collections Framework)

Java集合框架迭代器的使用

Java 的集合框架(如 ArrayListLinkedListHashSet 等)广泛使用了迭代器模式。每个集合类都实现了 Iterable 接口,并提供了 iterator() 方法来返回一个迭代器。

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class JavaCollectionExample {
   
    public static void main(String[] args) {
   
        List<String> list = new ArrayList<>();
        list.add("Apple");
        list.add("Banana");
        list.add("Cherry");

        // 使用迭代器遍历集合
        Iterator<String> iterator = list.iterator();
        while (iterator.hasNext()) {
   
            System.out.println(iterator.next());
        }
    }
}

Java集合框架迭代器的源码实现

Iterable接口:定义了iterator()方法,用于返回一个迭代器。

public interface Iterable<T> {
   
    Iterator<T> iterator();
}

Iterator接口:定义了遍历集合的方法,如hasNext()next()

public interface Iterator<E> {
   
    boolean hasNext();
    E next();
    void remove(); // 可选操作
}

ArrayList中的迭代器实现:

public Iterator<E> iterator() {
   
    return new Itr();
}

private class Itr implements Iterator<E> {
   
    int cursor;       // 当前遍历的位置
    int lastRet = -1; // 上一次返回的元素索引

    public boolean hasNext() {
   
        return cursor != size;
    }

    public E next() {
   
        // 返回当前元素,并移动游标
        // ...
    }

    public void remove() {
   
        // 删除上一次返回的元素
        // ...
    }
}

三、总结

迭代器模式的优点

  1. 解耦遍历逻辑与聚合对象
    • 将遍历逻辑从聚合对象中分离出来,聚合对象可以专注于数据存储,而迭代器负责遍历。
    • 符合单一职责原则。
  2. 统一遍历接口
    • 提供了一种统一的方式来遍历不同类型的聚合对象(如数组、链表、树等)。
    • 客户端代码无需关心聚合对象的内部结构。
  3. 支持多种遍历方式
    • 可以为同一个聚合对象定义多个迭代器,实现不同的遍历方式(如正序遍历、逆序遍历、深度优先遍历等)。
  4. 增强封装性
    • 隐藏了聚合对象的内部结构,客户端代码只能通过迭代器访问元素,无法直接操作聚合对象的内部数据。
  5. 开闭原则
    • 新增聚合类和迭代器类不会影响现有代码,易于扩展。

迭代器模式的缺点

  1. 增加复杂性
    • 对于简单的聚合对象,使用迭代器模式可能会增加代码复杂性。
    • 如果遍历逻辑非常简单,直接使用 for 循环可能更直观。
  2. 性能开销
    • 迭代器模式可能会引入额外的性能开销,尤其是在遍历大型数据集时。
  3. 不适合频繁修改的聚合对象
    • 如果聚合对象在遍历过程中频繁修改(如添加或删除元素),可能会导致迭代器失效或抛出异常。

迭代器模式的典型应用场景

  1. 集合框架
    • Java 的集合框架(如 ArrayList、LinkedList、HashSet 等)广泛使用了迭代器模式。
  2. 文件系统遍历
    • 遍历文件系统中的目录和文件时,可以使用迭代器模式封装遍历逻辑。
  3. 数据库查询结果遍历
    • 遍历数据库查询结果集时,可以使用迭代器模式提供统一的遍历接口。
  4. 树形结构遍历
    • 遍历树形结构(如 DOM 树、组织结构树等)时,可以使用迭代器模式支持多种遍历方式(如深度优先遍历、广度优先遍历等)。
目录
相关文章
|
6月前
|
设计模式 网络协议 Java
【设计模式】【行为型模式】状态模式(State)
一、入门 什么是状态模式? 状态模式(State Pattern)是一种行为设计模式,允许对象在其内部状态改变时改变其行为,使其看起来像是改变了类。状态模式的核心思想是将对象的状态封装成独立的类,并将
292 16
|
6月前
|
设计模式 算法 前端开发
【设计模式】【行为型模式】职责链模式(Chain of Responsibility)
一、入门 什么是职责链模式? 职责链模式是一种行为设计模式,它允许你将请求沿着一条链传递,直到有对象处理它为止。每个对象都有机会处理请求,或者将其传递给链中的下一个对象。 为什么需要职责链模式? 使用
262 16
|
6月前
|
设计模式 存储 Java
【设计模式】【行为型模式】备忘录模式(Memento)
一、入门 什么是备忘录模式? 备忘录模式(Memento Pattern)是一种行为设计模式,用于在不破坏封装性的前提下,捕获并外部化一个对象的内部状态,以便在需要时恢复该状态。它通常用于实现撤销操作
221 8
|
6月前
|
设计模式 消息中间件 Java
【设计模式】【行为型模式】命令模式(Command)
一、入门 什么是命令模式? 命令模式是一种行为设计模式,它将请求或操作封装为对象,从而使你可以用不同的请求对客户进行参数化,并支持请求的排队、记录、撤销等操作。 命令模式的核心是将“请求”封装为独立的
226 15
|
6月前
|
设计模式 算法 搜索推荐
【设计模式】【行为型模式】策略模式(Strategy)
一、入门 什么是策略模式? 策略模式是一种行为设计模式,允许在运行时选择算法或行为。它将算法封装在独立的类中,使得它们可以互换,而不影响客户端代码。 为什么需要策略模式? 策略模式的主要目的是解决算法
138 14
|
6月前
|
设计模式 数据采集 算法
【设计模式】【行为型模式】模板方法模式(Template Method)
一、入门 1.1、什么是模板方法模式? 模板模式(Template Method Pattern)是一种行为设计模式,它定义了一个算法的框架,并允许子类在不改变算法结构的情况下重新定义算法的某些步骤。
230 13
|
6月前
|
设计模式 Java 编译器
【设计模式】【行为型模式】解释器模式(Interpreter)
一、入门 什么是解释器模式? 解释器模式(Interpreter Pattern)是一种行为设计模式,用于定义语言的语法表示,并提供一个解释器来处理该语法。它通常用于需要解释和执行特定语言或表达式的场
169 11
|
6月前
|
设计模式 XML JSON
【设计模式】【行为型模式】访问者模式(Visitor)
一、入门 什么是访问者模式? 访问者模式(Visitor Pattern)是一种行为设计模式,允许你将算法与对象结构分离。通过这种方式,可以在不改变对象结构的情况下,向对象结构中的元素添加新的操作。
224 10
|
6月前
|
设计模式 Java 程序员
【设计模式】【行为型模式】中介者模式(Mediator)
一、入门 什么是中介者模式? 中介者模式(Mediator Pattern)是一种行为设计模式,旨在减少对象之间的直接依赖,通过引入一个中介者对象来协调多个对象之间的交互。这种模式特别适用于对象间存在
156 9
|
6月前
|
设计模式 消息中间件 存储
【设计模式】【行为型模式】观察者模式(Observer)
一、入门 什么是观察者模式? 观察者模式(Observer Pattern)是一种行为设计模式,它定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会收到通知并自动更新。
340 9