迭代器模式(Iterator Pattern)是一种行为型设计模式,通过封装遍历逻辑与解耦数据结构,为聚合对象(如集合)提供统一的元素访问方式,避免客户端依赖其内部实现。以下是该模式的系统性解析:
一、核心定义与设计目标
-
定义
迭代器模式将遍历聚合对象的职责委托给独立的迭代器对象,客户端通过迭代器接口(如hasNext()
、next()
)顺序访问元素,无需了解底层数据结构(如数组、链表或树)。例如,Java 的Collection
集合通过Iterator
接口统一遍历元素。 -
设计目标
- 解耦遍历与存储:聚合类专注数据管理,迭代器类处理遍历逻辑。
- 统一接口:为不同数据结构(数组、树)提供一致的访问方式。
- 支持多种遍历策略:如正序、逆序或过滤遍历。
二、模式结构与角色划分
-
核心角色
- 迭代器接口(Iterator):定义遍历方法(
hasNext()
、next()
)。 - 具体迭代器(ConcreteIterator):实现迭代逻辑(如数组索引、链表指针)。
- 聚合接口(Aggregate):声明创建迭代器的方法(如
createIterator()
)。 - 具体聚合类(ConcreteAggregate):存储数据并返回对应的迭代器实例。
- 迭代器接口(Iterator):定义遍历方法(
-
UML类图示例
+-------------------+ +-------------------+
| Aggregate |<|------|>| Iterator |
| +createIterator() | | +hasNext() |
+-------------------+ | +next() |
▲ +-------------------+
| ▲
| |
+-------------------+ +-------------------+
| ConcreteAggregate | | ConcreteIterator |
| +createIterator() | | +hasNext() |
+-------------------+ | +next() |
+-------------------+
- 双重分派机制
聚合类通过createIterator()
返回特定迭代器,客户端通过迭代器接口遍历元素,实现数据存储与访问的解耦。
三、优缺点分析
优点
- 高内聚低耦合:聚合类无需暴露内部结构,迭代器独立管理遍历逻辑。
- 扩展性强:新增遍历方式(如深度优先遍历树)只需扩展迭代器类。
- 简化客户端代码:统一接口屏蔽数据结构差异。
缺点
- 类膨胀:每个聚合类需对应一个迭代器类,增加系统复杂度。
- 性能损耗:频繁的迭代器对象创建和递归调用可能影响性能。
四、适用场景
- 异构集合遍历
- 统一处理数组、链表、树等不同结构的集合。
- 隐藏数据结构细节
- 第三方库提供集合时,避免暴露内部实现(如数据库查询结果集)。
- 动态遍历策略
- 支持按需切换遍历方式(如正序与逆序遍历)。
- 复杂业务规则处理
- 按条件过滤或转换元素(如电商订单状态筛选)。
五、实现示例(Java)
以自定义集合类为例:
// 1. 迭代器接口
interface Iterator<T> {
boolean hasNext();
T next();
}
// 2. 具体迭代器实现
class ArrayIterator<T> implements Iterator<T> {
private T[] array;
private int index = 0;
public ArrayIterator(T[] array) { this.array = array; }
@Override public boolean hasNext() { return index < array.length; }
@Override public T next() { return array[index++]; }
}
// 3. 聚合接口
interface Aggregate<T> {
Iterator<T> createIterator();
}
// 4. 具体聚合类
class MyCollection<T> implements Aggregate<T> {
private T[] elements;
public MyCollection(T[] elements) { this.elements = elements; }
@Override public Iterator<T> createIterator() { return new ArrayIterator<>(elements); }
}
// 客户端调用
public class Client {
public static void main(String[] args) {
String[] data = {"A", "B", "C"};
MyCollection<String> collection = new MyCollection<>(data);
Iterator<String> it = collection.createIterator();
while (it.hasNext()) System.out.println(it.next()); // 输出:A B C
}
}
六、实际应用案例
- Java集合框架
List
、Set
等集合通过iterator()
方法返回迭代器。
- Spring数据访问
JdbcTemplate
使用迭代器遍历数据库查询结果。
- 文件系统遍历
- 递归遍历文件夹及子文件时封装为迭代器。
七、与其他模式的对比
模式 | 核心差异 |
---|---|
访问者模式 | 迭代器模式关注遍历元素,访问者模式关注对元素的操作。 |
组合模式 | 组合模式统一处理树形结构,迭代器模式用于遍历该结构。 |
策略模式 | 策略模式动态切换算法,迭代器模式固定遍历逻辑但支持多种实现。 |
八、总结
迭代器模式通过分离遍历职责与统一访问接口,为复杂数据结构的遍历提供了标准化解决方案。其核心价值在于解耦客户端与聚合对象的内部实现,尤其适用于需要支持多种遍历策略或隐藏数据结构的场景(如框架设计与第三方库开发)。但需注意控制迭代器类的数量,避免过度设计。实际开发中,可结合工厂模式管理迭代器创建,或利用流式API(如Java Stream)简化遍历操作。对于高频遍历场景,建议通过缓存迭代器对象或预加载数据优化性能。