顿搜
迭代器模式(Iterator)——23种设计模式之行为型模式
04/22
在软件构建过程中,聚集对象内部结构常常变化各异。但对于这些聚集对象,我们希望在不暴露其内部结构的同时,可以让外部客户代码透明地访问其中包含的元素;同时这种“透明遍历”也为“同一种算法在多种聚集对象上进行操作”提供了可能。
将对聚集对象的访问和遍历从聚集对象中分离出来并放入一个迭代器(iterator)。将遍历机制与聚集对象分离使我们可以定义不同的迭代器来实现不同的遍历策略,而无需在聚集接口中列举它们。
一、知识补充
聚集对象拥有两个职责:
- ①、存储内部数据 :根本属性
- ②、遍历内部数据:可变化的、可分离的
- ③、可以将遍历行为分离出来,抽象为一个 迭代器,专门提供遍历聚集内部数据对象的行为,这就是迭代器模式的本质。
- ④、使用面向对象技术将这种遍历机制抽象为“迭代器对象”为“应对变化中的聚集对象”提供 了一种优雅的方式。
二、类图表示
迭代器模式涉及到Iterator(抽象迭代器),ConcreteIterator(具体迭代器),Aggregate(抽象聚集类),ConcreteAggregate(具体聚集类)等角色
- ①、Iterator(抽象迭代器):迭代器定义访问和遍历元素的接口
- ②、ConcreteIterator(具体迭代器):具体迭代器实现迭代器接口对该聚集遍历时跟踪当前位置
- ③、Aggregate(抽象聚集类):聚集定义创建相应迭代器对象的接口
- ④、ConcreteAggregate(具体聚集类):具体聚集实现创建相应迭代器的接口,该操作返回ConcreteIterator的一个适当的实例。

三、代码示例
public interface Aggregate {
public abstract Object createIterator();
public abstract Object get(int index);
}class ConcreteAggregate implements Aggregate{
public List<String> list = new ArrayList<String>();
@Override
public Object createIterator() {
return null;
}
@Override
public Object get(int index) {
if(index >= 0 ){
return list.get(index);
}
return null;
}
}public interface MyIterator {
public abstract Object first();
public abstract Object next();
public abstract boolean hasNext();
public abstract Object currentItem();
}class ConcreteMyIterator implements MyIterator{
public List<Object> list;
public int conrrent = 0;
public ConcreteMyIterator() {}
public ConcreteMyIterator( List<Object> list) {
this.list = list;
}
@Override
public Object first() {
if(list != null){
return list.get(0);
}
return null;
}
@Override
public Object next() {
if(conrrent < list.size()){
return list.get(conrrent + 1);
}
return list.get(conrrent);
}
@Override
public boolean hasNext() {
if(conrrent >= list.size()){
return false;
}
return true;
}
@Override
public Object currentItem() {
return list.get(conrrent);
}
}四、模式分析
聚集是一个管理和组织数据对象的数据结构。
- ①、聚集对象主要拥有两个职责:一是存储内部数据;二是遍历内部数据。
- ②、存储数据是聚集对象最基本的职责。
- ③、ConcreteIterator跟踪聚集中的当前对象,并能 够计算出待遍历的后继对象
五、迭代器类型
1、主动(Active)迭代器 vs. 被动(Passive)迭代器
- ①、主动:由客户调用next()等迭代方法
- ②、被动:迭代器自行推进遍历过程
2、静态迭代器 vs. 动态迭代器
- ①、静态:由聚集对象创建并持有聚集对象的快照,在产生后这个快照的内容不再变化
- ②、动态:迭代器保持对聚集元素的引用,任何对聚集内容的修改都会反映到迭代器对象上
3、过滤迭代器:扫过聚集元素的同时进行计算
六、优缺点分析
1、优点
- ①、它支持以不同的方式遍历一个聚集,复杂的聚 集可用多种方式进行遍历
- ②、迭代器简化了聚集的接口,有了迭代器的遍历 接口,聚集本身就不再需要类似的遍历接口了
- ③、在同一个聚集上可以有多个遍历,每个迭代器保持它自己的遍历状态。因此你可以同时进行 多个遍历。
2、缺点
- ①、给客户端聚集被顺序化的错觉;迭代器给出的聚集元素没有类型特征
七、模式间关系
1、与工厂方法模式的关系
- ①、在迭代器模式中蕴涵着工厂方法模式,聚集类充当了工厂类,迭代器类充当产品类。
- ②、多态迭代器
2、与组合模式的关系
- ①、Iterator常被应用到复合的递归结构上
3、与备忘录模式的关系
- ①、常用Memento来捕获一个迭代的状态
八、应用场景
访问一个聚集对象的内容而无需暴露它的内部表示。
- ①、支持对聚集对象的多种遍历。
- ②、为遍历不同的聚集结构提供一个统一的接口(即支持多态迭代)。
九、总结
迭代器模式在访问数组、集合、列表等数据时,尤其是数据库数据操作时,是非常普遍的应用。
- ①、迭代器(Iterator)模式把元素之间游走的任务交给 了迭代器,而不是聚集对象。这不仅让聚集的接口和实现变得更简洁,也让它专注于管理对象,而不必理会遍 历的事情。
- ②、在迭代器模式中应用了工厂方法模式,聚集类充当工厂类,而迭代器充当产品类,由于定义了抽象层, 系统的扩展性很好,在客户端可以针对抽象聚集类和抽象迭代器进行编程。
- ③、由于很多编程语言的类库都已经实现了迭代器模式,,因此在实际使用中我们很少自定义迭代器,只需要直接使用Java、C#等语言中已定义好的迭代器即可,迭代器已经成为我们操作聚集对象的基本工具之一。
- ④、将遍历聚集对象中数据的行为提取出来,封装到一 个迭代器中,通过专门的迭代器来遍历聚集对象的内部数据,这就是迭代器模式的本质。迭代器模式是“单一职责原则”的完美体现。