一、模式动机
一个聚合对象,如一个列表(List)或者一个集合(Set),应该提供一种方法来让别人可以访问它的元素,而又不需要暴露它的内部结构。
针对不同的需要,可能还要以不同的方式遍历整个聚合对象,但是我们并不希望在聚合对象的抽象层接口中充斥着各种不同遍历的操作。
在迭代器模式中,提供一个外部的迭代器来对聚合对象进行访问和遍历,迭代器定义了一个访问该聚合元素的接口,并且可以跟踪当前遍历的元素,了解哪些元素已经遍历过而哪些没有。
二、模式定义
迭代器模式(Iterator Pattern) :提供一种方法来访问聚合对象,而不用暴露这个对象的内部表示,其别名为游标(Cursor)。迭代器模式是一种对象行为型模式。
三、模式结构
四、参与者
- Iterator: 抽象迭代器
- ConcreteIterator: 具体迭代器
- Aggregate: 抽象聚合类
- ConcreteAggregate: 具体聚合类
五、示例代码
package design.pattern;
import java.util.ArrayList;
// 抽象迭代器
public abstract class Iterator {
public abstract Object first();
public abstract Object next();
public abstract boolean isDone();
public abstract Object currentItem();
public static void main(String[] args) {
ConcreteAggregate aggregate = new ConcreteAggregate();
aggregate.addItem("hello world");
aggregate.addItem(1);
aggregate.addItem(true);
ConcreteIterator iterator = (ConcreteIterator) aggregate.createIterator();
while (!iterator.isDone()) {
System.out.println(iterator.next());
}
}
}
// 具体迭代器
class ConcreteIterator extends Iterator {
private ConcreteAggregate aggregate;
private int current = 0;
public ConcreteIterator(ConcreteAggregate aggregate) {
this.aggregate = aggregate;
}
public Object first() {
return aggregate.getItem(0);
}
public Object next() {
Object ret = null;
if (current < aggregate.getCount()) {
ret = aggregate.getItem(current++);
}
return ret;
}
public Object currentItem() {
return aggregate.getItem(current);
}
public boolean isDone() {
return current >= aggregate.getCount();
}
}
// 抽象容器类
abstract class Aggregate {
public abstract Iterator createIterator();
}
// 具体容器类
class ConcreteAggregate extends Aggregate {
private ArrayList<Object> items = new ArrayList<>();
public Iterator createIterator() {
return new ConcreteIterator(this);
}
public int getCount() {
return items.size();
}
public Object getItem(int index) {
return items.get(index);
}
public void addItem(Object item) {
items.add(item);
}
}
模式结构
优点
- 它支持以不同的方式遍历一个聚合对象。
- 迭代器简化了聚合类。
- 在同一个聚合上可以有多个遍历。
- 在迭代器模式中,增加新的聚合类和迭代器类都很方便,无须修改原有代码,满足“开闭原则”的要求。
缺点
- 由于迭代器模式将存储数据和遍历数据的职责分离,增加新的聚合类需要对应增加新的迭代器类,类的个数成对增加,这在一定程度上增加了系统的复杂性。
模式使用
- 访问一个聚合对象的内容而无须暴露它的内部表示。
- 需要为聚合对象提供多种遍历方式。
- 为遍历不同的聚合结构提供一个统一的接口。