Java迭代器模式
1. 模式定义
迭代器模式是一种行为型设计模式,它允许在不暴露集合底层表现形式(列表、栈和树等)的情况下访问集合中的所有元素。
2. 模式结构
迭代器模式的主要组成部分:
- 抽象迭代器(Iterator):定义访问和遍历元素的接口。
- 具体迭代器(ConcreteIterator):实现 Iterator 接口,对集合进行遍历并跟踪迭代器的当前位置。
- 抽象聚合类(Aggregate):定义创建迭代器的接口。
- 具体聚合类(ConcreteAggregate):实现 Aggregate 接口,提供迭代器以遍历其元素。
3. 代码示例
下面是一个使用迭代器模式的简单示例,其中 Book
表示图书类,BookShelf
表示存储图书的书架类,Iterator
表示抽象迭代器接口,BookShelfIterator
表示具体迭代器实现类。
// Book.java
public class Book {
private String title;
private String author;
public Book(String title, String author) {
this.title = title;
this.author = author;
}
public String getTitle() {
return title;
}
public String getAuthor() {
return author;
}
}
// Iterator.java
public interface Iterator<T> {
boolean hasNext();
T next();
}
// BookShelfIterator.java
public class BookShelfIterator implements Iterator<Book> {
private BookShelf bookShelf;
private int index;
public BookShelfIterator(BookShelf bookShelf) {
this.bookShelf = bookShelf;
this.index = 0;
}
public boolean hasNext() {
return index < bookShelf.getLength();
}
public Book next() {
Book book = bookShelf.getBookAt(index);
index++;
return book;
}
}
// Aggregate.java
public interface Aggregate<T> {
Iterator<T> iterator();
}
// BookShelf.java
public class BookShelf implements Aggregate<Book> {
private Book[] books;
private int last;
public BookShelf(int maxsize) {
this.books = new Book[maxsize];
this.last = 0;
}
public Book getBookAt(int index) {
return books[index];
}
public void appendBook(Book book) {
this.books[last] = book;
last++;
}
public int getLength() {
return last;
}
public Iterator<Book> iterator() {
return new BookShelfIterator(this);
}
}
4. 优缺点说明
4.1 优点
- 单一职责原则。迭代器模式将遍历集合元素的责任封装到迭代器中,而不是在聚合对象中,使聚合对象更加简单。
- 开放/封闭原则。迭代器模式使您能够在不更改聚合对象代码的情况下添加新的迭代器。
- 通过使用迭代器,客户端代码从具体聚合中分离出来,从而更加简单,代码更易于维护。
- 迭代器模式使得代码更加灵活,因为您可以在运行时修改迭代算法。
4.2 缺点
- 迭代器模式增加了代码的复杂性,以及运行时的性能开销。
- 一些语言提供了内置的迭代器结构,使得实现迭代器模式时显得多余。
- 当迭代算法在整个聚合上是固定的时,迭代器模式可能不是最优选择,因为这需要实现大量的代码。
5. 使用场景和总结
适合使用迭代器模式的情况包括:
- 当需要对聚合对象进行遍历,并且不想暴露底层集合的表现形式时。
- 当希望对同一个聚合对象具有不同的遍历方式时。
- 当需要提供对聚合对象的多个遍历时,而又不想暴露底层表现形式时。
总之,迭代器模式通过提供一个抽象接口来分离遍历的行为和聚合对象的实现。这种分离增加了代码的复杂性,但也使得代码更加灵活,易于维护和扩展。