行为模式-迭代器模式

发布于:2025-06-16 ⋅ 阅读:(18) ⋅ 点赞:(0)

定义:

        Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation.(它提供一种方法访问一个容器对象中各个元素,而又不需暴露该 对象的内部细节。)

迭代器模式通用类图

        迭代器设计模式的核心是将集合对象的遍历行为抽象出来,封装到一个独立的迭代器对象中。这样,集合对象就不需要自己实现遍历逻辑,而是将遍历的责任委托给迭代器对象。客户端只需要通过迭代器提供的接口来访问集合元素,而不需要了解集合的内部结构。这种设计方式不仅使集合的接口和实现更加简洁,还可以支持多种不同的遍历方式,提高了代码的可维护性和可扩展性。

角色:

迭代器模式包含以下几个核心角色:

1、迭代器接口(Iterator)

        迭代器接口定义了访问和遍历元素的方法,如`hasNext()`(判断是否还有下一个元素)、`next()`(返回下一个元素)等。所有具体迭代器都必须实现这个接口,确保客户端可以以统一的方式使用迭代器。

2、具体迭代器(Concrete Iterator)

        具体迭代器实现了迭代器接口,负责跟踪集合中元素的当前位置,并实现各种遍历方法。具体迭代器通常会持有一个对具体集合对象的引用,以便访问集合中的元素。

3、集合接口(Aggregate)

        集合接口定义了创建迭代器对象的方法,如`createIterator()`。所有具体集合都必须实现这个接口,以便客户端可以请求创建适合该集合的迭代器。

4、具体集合(Concrete Aggregate)

        具体集合实现了集合接口,负责创建相应的具体迭代器对象。具体集合通常包含一个存储元素的数据结构,如数组、列表等。

代码示例:

        下面通过一个简单的示例来展示迭代器设计模式的实现。假设我们有一个自定义的书架类,需要实现对书架上书籍的遍历功能。

// 书籍类

public class Book {

    private String name;

    private String author;


    public Book(String name, String author) {

        this.name = name;

        this.author = author;

    }



    public String getName() {

        return name;

    }



    public String getAuthor() {

        return author;

    }



    @Override

    public String toString() {

        return "《" + name + "》 - " + author;

    }

}

// 迭代器接口

public interface Iterator<T> {

    boolean hasNext();

    T next();

}

// 具体迭代器:书架迭代器

public class BookShelfIterator implements Iterator<Book> {

    private BookShelf bookShelf;

    private int index;



    public BookShelfIterator(BookShelf bookShelf) {

        this.bookShelf = bookShelf;

        this.index = 0;

    }



    @Override

    public boolean hasNext() {

        return index < bookShelf.getLength();

    }



    @Override

    public Book next() {

        Book book = bookShelf.getBookAt(index);

        index++;

        return book;

    }

}

// 集合接口

public interface Aggregate<T> {

    Iterator<T> createIterator();

}

// 具体集合:书架

public class BookShelf implements Aggregate<Book> {

    private Book[] books;

    private int last = 0;



    public BookShelf(int maxSize) {

        this.books = new Book[maxSize];

    }



    public Book getBookAt(int index) {

        return books[index];

    }



    public void appendBook(Book book) {

        this.books[last] = book;

        last++;

    }



    public int getLength() {

        return last;

    }



    @Override

    public Iterator<Book> createIterator() {

        return new BookShelfIterator(this);

    }

}

// 客户端代码

public class IteratorPatternClient {

    public static void main(String[] args) {

        // 创建书架并添加书籍

        BookShelf bookShelf = new BookShelf(4);

        bookShelf.appendBook(new Book("Java编程思想", "Bruce Eckel"));

        bookShelf.appendBook(new Book("设计模式", "Erich Gamma"));

        bookShelf.appendBook(new Book("算法导论", "Thomas H. Cormen"));

        bookShelf.appendBook(new Book("计算机程序的构造和解释", "Harold Abelson"));



        // 使用迭代器遍历书架上的书籍

        Iterator<Book> iterator = bookShelf.createIterator();

        System.out.println("书架上的书籍:");

        while (iterator.hasNext()) {

            Book book = iterator.next();

            System.out.println(book);

        }

    }

}

优点 :

1、支持多种遍历方式:迭代器模式可以为一个聚合对象提供多种不同的遍历方式,客户端可以根据需要选择合适的迭代器,而不需要修改聚合对象的代码。

2、简化聚合对象的接口:迭代器模式将遍历逻辑从聚合对象中分离出来,使得聚合对象的接口更加简洁,只需要关注元素的存储和管理,而不需要关注遍历逻辑。

3、符合单一职责原则:迭代器模式将遍历逻辑封装在迭代器类中,使得聚合对象和迭代器类各自承担自己的职责,符合单一职责原则。

4、符合开闭原则:迭代器模式可以在不修改聚合对象代码的情况下,通过增加新的迭代器类来支持新的遍历方式,符合开闭原则。

5、隐藏聚合对象的内部结构:迭代器模式可以将聚合对象的内部结构隐藏起来,客户端只需要通过迭代器提供的接口访问元素,提高了系统的安全性。


缺点:

1、增加类的数量:迭代器模式需要定义迭代器接口、具体迭代器类、聚合接口和具体聚合类等多个类,会增加系统的类数量,使代码结构变得复杂。

2、对于简单的聚合结构可能过于繁琐:对于简单的聚合结构,如数组,直接使用循环遍历可能更加简单和高效,使用迭代器模式可能会显得过于繁琐。

3、迭代器的维护成本:当聚合对象的内部结构发生变化时,可能需要修改迭代器的实现,增加了维护成本。


使用场景: 

(一)需要为聚合对象提供多种遍历方式

        当一个聚合对象需要支持多种不同的遍历方式时,如正向遍历、反向遍历、跳跃遍历等,可以使用迭代器模式将不同的遍历逻辑封装到不同的迭代器类中,客户端可以根据需要选择合适的迭代器。

(二)需要隐藏聚合对象的内部结构

        迭代器模式可以将聚合对象的内部结构隐藏起来,客户端只需要通过迭代器提供的接口访问元素,而不需要了解聚合对象的具体实现。这样可以保护聚合对象的内部数据不被非法访问。

(三)需要为不同的聚合结构提供统一的遍历接口

        当系统中存在多种不同类型的聚合结构(如数组、列表、树等),且需要为它们提供统一的遍历接口时,迭代器模式可以定义一个统一的迭代器接口,不同的聚合结构实现各自的具体迭代器,使得客户端可以使用相同的代码遍历不同的聚合结构。

(四)需要在遍历的同时对元素进行特定操作

        在遍历聚合对象的过程中,可能需要对元素进行特定的操作,如过滤、转换等。迭代器模式可以在迭代器中实现这些操作,使得遍历和操作可以同时进行,提高代码的灵活性。

        迭代器设计模式通过将集合对象的遍历行为抽象出来,封装到独立的迭代器对象中,为我们提供了一种统一且灵活的方式来访问集合元素。它在不暴露集合内部结构的情况下,支持多种遍历方式,简化了集合接口,提高了代码的可维护性和可扩展性。在实际开发中,当我们需要处理集合的遍历问题,特别是需要支持多种遍历方式或隐藏集合内部结构时,迭代器模式是一个不错的选择。但也要注意避免在简单场景中过度使用,以免增加系统的复杂性。掌握迭代器设计模式,能够让我们的代码更加简洁、灵活和易于维护。


网站公告

今日签到

点亮在社区的每一天
去签到