定义
提供一种统一的接口来遍历不同的聚合对象(如集合、数组或其他包含多个元素的对象结构),而无需暴露该对象内部的表示。通过引入迭代器,用户可以按顺序访问聚合内的元素,而不用关心底层数据结构的具体实现。
优缺点
优点:
- 封装性:通过迭代器接口,客户端代码无需了解底层数据结构的具体实现细节,只需使用统一的迭代方法即可遍历集合中的元素。
- 简化编码:为不同的数据结构提供了统一的访问方式,使得算法设计可以独立于数据结构。这样在处理不同类型的聚合对象时,客户端代码可以保持一致,不需要针对每种数据结构编写特定的遍历逻辑。
- 支持多种遍历方式:可以根据需求提供多种迭代器实现,如顺序迭代、逆序迭代、过滤迭代等,以满足不同的业务场景。
- 灵活性与可扩展性:可以在不修改原有类库的基础上添加新的迭代器,增强了系统的灵活性和可扩展性。
- 遵循单一职责原则:将数据存储和数据遍历的功能分离,每个类都专注于自己的职责。
缺点:
- 增加系统复杂性:对于简单的数据结构或小型项目来说,引入迭代器模式可能会增加系统的复杂性,如果直接使用内置的循环遍历可能更为简单。
- 无法直接进行随机访问:标准的迭代器通常只支持按顺序访问,若要支持随机访问则需要额外设计(例如Java中的ListIterator)。
- 内存和性能开销:创建迭代器实例会带来一定的内存开销,尤其是对于大型集合而言。此外,某些自定义迭代器的实现可能会导致性能下降,比如在遍历过程中涉及复杂的计算或状态跟踪。
- 不符合部分语言特性:对于支持内部迭代的语言(如Python),外部迭代器(即迭代器模式)有时显得冗余,因为可以直接对集合进行for循环遍历。
结构图和示例
- Iterator类:迭代器接口类,定义遍历元素所需要的方法,一般有以下几个方法,获取开始对象first(),获取下一个对象next(),判断是否到结尾isDone(),获取当前对象currentItem()
- ConcreteIterator类:具体迭代器类,实现迭代器接口中定义的方法
- Aggregate类:容器角色,一般提供一个 iterator()方法,例如java中的Collection接口,List接口, Set接口等
- ConcreteAggregate类:抽象容器类的具体实现,比如List的实现 ArrayList等
/**
* 抽象迭代类
*/
public interface Iterator {
public Object first();
public Object next();
public boolean isDone();
public Object currentItem();
}
/**
* 抽象容器类
*/
abstract class Aggregate {
public abstract Iterator createIterator();
}
/**
* 具体迭代器类,继承Iterator
*/
public class ConcreteIterator implements Iterator {
private final ConcreteAggregate concreteAggregate;
private int current = 0;
public ConcreteIterator(ConcreteAggregate concreteAggregate) {
this.concreteAggregate = concreteAggregate;
}
@Override
public Object first() {
return concreteAggregate.get(0);
}
@Override
public Object next() {
Object ret = null;
current++;
if (current < concreteAggregate.count()) {
ret = concreteAggregate.get(current);
}
return ret;
}
@Override
public boolean isDone() {
return current >= concreteAggregate.count();
}
@Override
public Object currentItem() {
return concreteAggregate.get(current);
}
}
/**
* 具体容器类,继承Aggregate
*/
public class ConcreteAggregate extends Aggregate {
private List<Object> items = new ArrayList<>();
@Override
public Iterator createIterator() {
return new ConcreteIterator(this);
}
public int count() {
return items.size();
}
public Object get(int index) {
return items.get(index);
}
public void add(Object value) {
items.add(value);
}
public void set(int index, Object value) {
items.set(index, value);
}
}
public class Test {
public static void main(String[] args) {
ConcreteAggregate a = new ConcreteAggregate();
a.add("小明");
a.add("小李");
a.add("小红");
Iterator i = a.createIterator();
while (!i.isDone()) {
System.out.printf("%s 你好!\n", i.currentItem());
i.next();
}
}
}