一、概述
存储多个成员对象(元素)的类称为聚合类(Aggregate Classes),对应的对象称为聚合对象。
聚合对象拥有两个职责:一是存储数据,二是遍历数据。可以将遍历数据的行为从聚合对象中分离出来,封装在一个“迭代器”对象中,由迭代器来提供遍历聚合对象内部数据的行为。
迭代器模式的定义为:提供一种方法来访问聚合对象,而不用暴露这个对象的内部表示,其别名为游标(Cursor),迭代器模式是一种对象行为型模式。
迭代器模式应用了工厂方法模式,结构图为:

二、示例代码
迭代器模式中应用了工厂方法模式,抽象迭代器(Iterator)对应抽象产品角色,具体迭代器(ConcreteIterator)对应具体产品角色,抽象聚合类(Aggregate)对应抽象工厂角色,具体聚合类(ConcreteAggregate)对应具体工厂角色。
抽象迭代器(Iterator)声明了用于遍历聚合对象中所存储元素的方法,典型代码如下:
1 | public interface Iterator { |
具体迭代器(ConcreteIterator)实现了抽象迭代器声明的遍历数据的方法,典型代码如下:
1 | public class ConcreteIterator implements Iterator { |
抽象聚合类(Aggregate)用于存储数据并负责创建迭代器对象,典型代码如下:
1 | public interface Aggregate { |
具体聚合类(ConcreAggregate)一方面负责存储数据,另一方面实现在抽象聚合类中声明的工厂方法createItarator(),典型代码如下:
1 | public class ConcreteAggregate implements Aggregate { |
具体迭代器类和具体聚合类之间存在双重关系,其中一个关系为关联关系,在具体迭代器中需要维持一个对具体聚合对象的引用,该关联关系的目的是访问存储在聚合对象中的数据,以便迭代器能够对这些数据进行遍历操作。
除了使用关联关系外,也可以将迭代器类设计为聚合类的内部类。
三、Collection和Iterator
Collection接口和Iterator接口充当了迭代器模式的抽象层,分别对应于抽象聚合类和抽象迭代器,而Collection接口的子类充当了具体聚合类,以List为例,结构图为:

三、demo
展示不同种类电视的电视频道。
抽象迭代器类(Iterator)设计如下:
1 | public interface TVIterator { |
抽象聚合类(Aggregate)设计如下:
1 | public interface Television { |
具体聚合类(ConcreAggregate)将具体迭代器设置为内部类,代码设计如下:
1 | public class TCLTelevision implements Television{ |
1 | public class SkyworthTelevision implements Television{ |
客户端调用方法如下:
1 | public class Client { |
代码运行结果如下:

四、总结
1. 优点
- 它支持以不同的方式遍历一个聚合对象,在同一个聚合对象上可以定义多种遍历方式。在迭代器模式中只需要用一个不同的迭代器来替换原有迭代器即可改变遍历算法,我们也可以自己定义迭代器的子类以支持新的遍历方式。
- 迭代器简化了聚合类。由于引入了迭代器,在原有的聚合对象中不需要再自行提供数据遍历等方法,这样可以简化聚合类的设计。
- 在迭代器模式中,由于引入了抽象层,增加新的聚合类和迭代器类都很方便,无须修改原有代码,满足“开闭原则”的要求。
2. 缺点
- 由于迭代器模式将存储数据和遍历数据的职责分离,增加新的聚合类需要对应增加新的迭代器类,类的个数成对增加,这在一定程度上增加了系统的复杂性。
- 抽象迭代器的设计难度较大,需要充分考虑到系统将来的扩展,例如JDK内置迭代器Iterator就无法实现逆向遍历,如果需要实现逆向遍历,只能通过其子类ListIterator等来实现,而ListIterator迭代器无法用于操作Set类型的聚合对象。在自定义迭代器时,创建一个考虑全面的抽象迭代器并不是件很容易的事情。
3. 适用场景
- 访问一个聚合对象的内容而无须暴露它的内部表示。将聚合对象的访问与内部数据的存储分离,使得访问聚合对象时无须了解其内部实现细节。
- 需要为一个聚合对象提供多种遍历方式。
- 为遍历不同的聚合结构提供一个统一的接口,在该接口的实现类中为不同的聚合结构提供不同的遍历方式,而客户端可以一致性地操作该接口。