迭代器模式
解决问题
提供一种方法顺序访问一个聚合对象中各个元素, 而又无须暴露该对象的内部表示。
方案
把在元素之间游走的责任交给迭代器,而不是聚合对象。
结构
- 抽象迭代器(Iterator): 迭代器定义访问和遍历元素的接口。
- 具体迭代器(ConcreteIterator): 具体迭代器实现迭代器Iterator接口。对该聚合遍历时跟踪当前位置。
- 抽象聚合类(Aggregate): 聚合定义创建相应迭代器对象的接口。
- 具体聚合类(ConcreteAggregate): 体聚合实现创建相应迭代器的接口,该操作返回ConcreteIterator的一个适当的实例。
适用性
- 访问一个聚合对象的内容而无需暴露它的内部表示。
- 需要为聚合对象提供多种遍历方式。
- 为遍历不同的聚合结构提供一个统一的接口 (即, 支持多态迭代)
优缺点
优点
- 它支持以不同的方式遍历一个聚合对象。
- 迭代器简化了聚合类。
- 在同一个聚合上可以有多个遍历。
- 在迭代器模式中,增加新的聚合类和迭代器类都很方便,无须修改原有代码。
缺点
迭代器模式将存储数据和遍历数据的职责分离,增加新的聚合类需要对应增加新的迭代器类.
经典实现
Collection实现
// 抽象聚合类
public interface Collection_<E> {
void add(E o);
int size();
Iterator_ iterator();
}
// 抽象迭代器
public interface Iterator_<E> { //Element //Type //K //Value V Tank
boolean hasNext();
E next(); //Tank next() Iterator_<Tank> it = ... Tank t = it.next();
}
// 具体的聚合类
class ArrayList_<E> implements Collection_<E> {
E[] objects = (E[])new Object[10];
//objects中下一个空的位置在哪儿,或者说,目前容器中有多少个元素
private int index = 0;
public void add(E o) {
if(index == objects.length) {
E[] newObjects = (E[])new Object[objects.length*2];
System.arraycopy(objects, 0, newObjects, 0, objects.length);
objects = newObjects;
}
objects[index] = o;
index ++;
}
public int size() {
return index;
}
@Override
public Iterator_<E> iterator() {
return new ArrayListIterator();
}
// 具体的迭代器 以内部类方式实现.
private class ArrayListIterator<E> implements Iterator_<E> {
private int currentIndex = 0;
@Override
public boolean hasNext() {
if(currentIndex >= index) return false;
return true;
}
@Override
public E next() {
E o = (E)objects[currentIndex];
currentIndex ++;
return o;
}
}
}
框架中使用
java聚集类(Collection).