Skip to main content

迭代器模式 (Iterator)

场景问题​

问题案例​

考虑一个自定义集合类,需要为用户提供遍历集合元素的功能,但不希望暴露集合的内部结构。

不用模式的解决方案​

实现简化版本​

最直接的做法是集合类直接暴露内部数据结构:

public class MyCollection {
private List<String> data = new ArrayList<>();
public void add(String s) { data.add(s); }
public List<String> getData() { return data; }
}

使用示例​

MyCollection col = new MyCollection();
col.add("A");
col.add("B");
for (String s : col.getData()) {
System.out.println(s);
}

有何问题​

  1. 破坏了封装性,暴露了内部实现。
  2. 客户端依赖具体的数据结构,扩展性差。

解决方案​

迭代器模式的定义​

提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露该对象的内部表示。

应用迭代器模式的思路​

  • 定义统一的迭代器接口,封装遍历逻辑。
  • 集合类实现创建迭代器的方法。
  • 客户端通过迭代器访问集合元素。

迭代器模式的结构​

  • Iterator:抽象迭代器,定义遍历接口。
  • ConcreteIterator:具体迭代器,实现遍历逻辑。
  • Aggregate:抽象聚合,定义创建迭代器方法。
  • ConcreteAggregate:具体聚合,实现集合存储和迭代器创建。

迭代器模式的实现​

// 迭代器接口
public interface Iterator {
boolean hasNext();
String next();
}

// 具体迭代器
public class MyIterator implements Iterator {
private List<String> data;
private int index = 0;
public MyIterator(List<String> data) { this.data = data; }
public boolean hasNext() { return index < data.size(); }
public String next() { return data.get(index++); }
}

// 聚合类
public class MyCollection {
private List<String> data = new ArrayList<>();
public void add(String s) { data.add(s); }
public Iterator createIterator() { return new MyIterator(data); }
}

使用示例​

public class Client {
public static void main(String[] args) {
MyCollection col = new MyCollection();
col.add("A");
col.add("B");
Iterator it = col.createIterator();
while (it.hasNext()) {
System.out.println(it.next());
}
}
}

迭代器重写示例​

示例结构​


示例代码​

见上文"迭代器模式的实现"部分。


模式讲解​

迭代器模式的功能​

  • 封装遍历逻辑,隐藏集合内部结构。
  • 支持多种遍历方式,扩展灵活。

实现成接口​

  • 迭代器和聚合类通常定义为接口或抽象类。

使用工厂方法​

  • 可结合工厂方法模式,统一创建迭代器对象。

切换产品簇​

  • 可用于切换不同类型的集合和遍历方式。

执行时序图​