迭代器模式 (Iterator Pattern)
提供一种方法顺序访问一个聚合对象中各个元素,而又不需暴露该对象的内部表示
模式定义
迭代器模式是一种行为型设计模式,它提供一种方法顺序访问一个聚合对象中各个元素,而又不需暴露该对象的内部表示。迭代器模式将聚合对象的遍历行为抽象出来,使得可以不关心聚合对象的内部结构就能遍历其中的元素。迭代器模式分离了聚合对象的遍历行为,使得可以在不暴露内部结构的情况下顺序访问聚合对象中的元素。
模式结构
graph TD
A[Iterator] --> B[ConcreteIterator]
C[Aggregate] --> D[ConcreteAggregate]
D --> B
实现方式
基础实现
定义迭代器接口和聚合接口,实现具体迭代器和具体聚合类。
// 迭代器接口
public interface Iterator {
boolean hasNext();
T next();
}
// 聚合接口
interface Aggregate {
Iterator createIterator();
}
// 具体迭代器
class BookIterator implements Iterator {
private Book[] books;
private int position = 0;
public BookIterator(Book[] books) {
this.books = books;
}
@Override
public boolean hasNext() {
return position < books.length && books[position] != null;
}
@Override
public Book next() {
return books[position++];
}
}
// 具体聚合类
class BookCollection implements Aggregate {
private Book[] books;
private int numberOfBooks = 0;
public BookCollection(int capacity) {
books = new Book[capacity];
}
public void addBook(Book book) {
if (numberOfBooks < books.length) {
books[numberOfBooks] = book;
numberOfBooks++;
}
}
public Book getBook(int index) {
if (index < numberOfBooks) {
return books[index];
}
return null;
}
public int getNumberOfBooks() {
return numberOfBooks;
}
@Override
public Iterator createIterator() {
return new BookIterator(books);
}
}
// 数据类
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 + "》 by " + author;
}
}
使用示例
public class IteratorPatternDemo {
public static void main(String[] args) {
BookCollection collection = new BookCollection(10);
collection.addBook(new Book("设计模式", "四人组"));
collection.addBook(new Book("Java编程思想", "Bruce Eckel"));
collection.addBook(new Book("重构", "Martin Fowler"));
collection.addBook(new Book("代码大全", "Steve McConnell"));
Iterator iterator = collection.createIterator();
System.out.println("书籍列表:");
while (iterator.hasNext()) {
Book book = iterator.next();
System.out.println(book);
}
}
}
经典案例
1. Java集合框架中的Iterator
Java集合框架广泛使用了迭代器模式,所有Collection接口的实现类都提供了iterator()方法:
List list = new ArrayList<>();
list.add("Apple");
list.add("Banana");
list.add("Orange");
// 使用迭代器遍历
Iterator iterator = list.iterator();
while (iterator.hasNext()) {
String fruit = iterator.next();
System.out.println(fruit);
// 可以安全地删除元素
if ("Banana".equals(fruit)) {
iterator.remove();
}
}
// 增强for循环实际上是迭代器的语法糖
for (String fruit : list) {
System.out.println(fruit);
}
2. 数据库结果集遍历
JDBC中的ResultSet接口也体现了迭代器模式的思想:
Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM users");
while (rs.next()) {
String name = rs.getString("name");
int age = rs.getInt("age");
System.out.println("姓名: " + name + ", 年龄: " + age);
}
3. 文件系统遍历
文件系统中的目录遍历也可以使用迭代器模式:
public class FileSystemIterator implements Iterator {
private Queue files = new LinkedList<>();
public FileSystemIterator(File root) {
if (root.isDirectory()) {
files.addAll(Arrays.asList(root.listFiles()));
} else {
files.add(root);
}
}
@Override
public boolean hasNext() {
return !files.isEmpty();
}
@Override
public File next() {
File file = files.poll();
if (file.isDirectory()) {
files.addAll(Arrays.asList(file.listFiles()));
}
return file;
}
}
应用场景
- 访问不同数据结构中的元素:如列表、树、图等
- 隐藏数据结构的内部实现细节
- 提供多种遍历方式:正向、反向、按条件筛选等
- 同时进行多个遍历操作而互不影响
- 简化聚合类的接口设计
- 统一不同聚合结构的访问接口
优缺点
优点
- 简化聚合类接口:聚合类不需要提供复杂的遍历接口
- 支持多种遍历方式:同一个聚合可以有多个不同的迭代器
- 多遍历并行操作:可以同时使用多个迭代器遍历同一聚合
- 解耦遍历算法和数据结构:新增遍历方式无需修改聚合类
- 符合单一职责原则:聚合负责数据管理,迭代器负责遍历
缺点
- 增加类的数量:每种聚合都需要对应的迭代器实现
- 可能浪费资源:对于简单的集合可能显得过于复杂
- 间接访问效率较低:通过迭代器访问元素比直接访问效率低