定义
提供一种方法顺序访问一个聚合对象中的各个元素,而又不需暴露对象的内部表示。
结构和说明
示例代码
public class IteratorDemo {
/**
* 迭代器接口,定义访问和遍历元素的操作
*/
public static interface Iterator {
/**
* 移动到聚合对象的第一个位置
*/
void first();
/**
* 移动到聚合对象的下一个位置
*/
void next();
/**
* 判断是否已经移动到聚合对象的最后一个位置
*
* @return true 表示已经移动到聚合对象的最后一个位置; false 反之
*/
boolean isDone();
/**
* 获取迭代的当前元素
*
* @return 迭代的当前元素
*/
Object currentItem();
}
/**
* 具体的迭代器实现对象,示意的是聚合对象为数组的迭代器
* 不同的聚合对象相应的迭代器实现是不一样的
*/
public static class ConcreteIterator implements Iterator {
/**
* 持有被迭代的具体的聚合对象
*/
private ConcreteAggregate aggregate;
/**
* 内部索引,记录当前迭代到的索引位置
* -1表示刚开始的时候,迭代器指向聚合对象第一个对象之前
*/
private int index = -1;
/**
* 构造方法,传入被迭代的具体的聚合对象
*
* @param aggregate 被迭代的具体的聚合对象
*/
public ConcreteIterator(ConcreteAggregate aggregate) {
this.aggregate = aggregate;
}
@Override
public void first() {
index = 0;
}
@Override
public void next() {
if (index < aggregate.size()) {
index = index + 1;
}
}
@Override
public boolean isDone() {
return index >= aggregate.size();
}
@Override
public Object currentItem() {
return aggregate.get(index);
}
}
/**
* 聚合对象的接口,定义创建相应迭代器对象的接口
*/
public static abstract class Aggregate {
/**
* 工厂方法,创建相应迭代器对象的接口
*
* @return 相应迭代器对象的接口
*/
public abstract Iterator createIterator();
}
/**
* 具体的聚合对象,实现创建相应迭代器对象的功能
*/
public static class ConcreteAggregate extends Aggregate {
/**
* 示意,表示聚合对象具体的内容
*/
private String[] ss = null;
/**
* 构造方法,传入聚合对象具体的内容
*
* @param ss 聚合对象具体的内容
*/
public ConcreteAggregate(String[] ss) {
this.ss = ss;
}
@Override
public Iterator createIterator() {
return new ConcreteIterator(this);
}
/**
* 获取索引所对应的元素
*
* @param index 索引
* @return 索引对应的元素
*/
public Object get(int index) {
if (index >= ss.length) {
return null;
}
return ss[index];
}
/**
* 获取聚合对象大小
*
* @return 聚合对象的大小
*/
public int size() {
return ss.length;
}
}
public static class Client {
public static void main(String[] args) {
Aggregate aggregate = new ConcreteAggregate(new String[]{"张三", "李四", "王二", "麻子"});
Iterator iterator = aggregate.createIterator();
// 首先设置迭代器到第一个元素
iterator.first();
while (!iterator.isDone()) {
Object currentItem = iterator.currentItem();
System.out.println("currentItem = " + currentItem);
iterator.next();
}
}
}
}
调用顺序
优缺点
优点
- 更好的封装性
- 迭代器模式可以让你访问一个聚合对象的内容,而无须暴露该聚合对象的内部表示,从而提高聚合对象的封装性
- 可以以不同的遍历方式来遍历一个聚合
- 使用迭代器模式,是的聚合对象的内容和具体的迭代算法分离。这样可以通过使用不同的迭代器实例、不同的遍历方式来遍历一个聚合对象了。
- 迭代器简化了聚合接口。
- 有了迭代器接口,则聚合本身就不需要再定义这些接口了,从而简化了聚合的接口定义。
- 简化客户端调用
- 迭代器为遍历不同的聚合对象提供了一个统一的接口,使得客户端遍历聚合对象的内容变得更简单。
- 同一个聚合可以有多个遍历
- 每个迭代器保持它自己的遍历状态,比如前面实现中的迭代索引位置,因此可以对同一个聚合对象同时进行多个遍历。
思考
本质
控制访问聚合对象中的元素。
何时选用
- 如果你希望提供一个聚合对象的内容,但是又不想暴露它的内部表示的时候,可以使用迭代器模式来提供迭代器接口,从而让客户端只是通过迭代器接口来访问聚合对象,而无须关心聚合对象的内部实现。
- 如果你希望有多种遍历方式可以访问聚合对象,可以使用迭代器模式。
- 如果你希望为遍历不同的聚合对象提供一个统一的接口,可以使用迭代器模式。
相关模式
- 迭代器模式和组合模式
这两个模式可以组合使用。
组合模式是一种递归的对象结构,在枚举某个组合对象的子对象的时候,通常会使用迭代器模式。
- 迭代器模式和工厂方法模式
这两个模式可以组合使用。
在聚合对象创建迭代器的时候,通常会采用工厂方法模式来实例化相应的迭代器对象。