迭代器模式 (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);
}
有何问题
- 破坏了封装性,暴露了内部实现。
- 客户端依赖具体的数据结构,扩展性差。
解决方案
迭代器模式的定义
提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露该对象的内部表示。
应用迭代器模式的思路
- 定义统一的迭代器接口,封装遍历逻辑。
- 集合类实现创建迭代器的方法。
- 客户端通过迭代器访问集合元素。
迭代器模式的结构
- 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());
}
}
}
迭代器重写示例
示例结构
示例代码
见上文"迭代器模式的实现"部分。
模式讲解
迭代器模式的功能
- 封装遍历逻辑,隐藏集合内部结构。
- 支持多种遍历方式,扩展灵活。
实现成接口
- 迭代器和聚合类通常定义为接口或抽象类。
使用工厂方法
- 可结合工厂方法模式,统一创建迭代器对象。
切换产品簇
- 可用于切换不同类型的集合和遍历方式。