迭代器模式

82 阅读3分钟

定义

提供一种统一的接口来遍历不同的聚合对象(如集合、数组或其他包含多个元素的对象结构),而无需暴露该对象内部的表示。通过引入迭代器,用户可以按顺序访问聚合内的元素,而不用关心底层数据结构的具体实现。

优缺点

优点:

  1. 封装性:通过迭代器接口,客户端代码无需了解底层数据结构的具体实现细节,只需使用统一的迭代方法即可遍历集合中的元素。
  2. 简化编码:为不同的数据结构提供了统一的访问方式,使得算法设计可以独立于数据结构。这样在处理不同类型的聚合对象时,客户端代码可以保持一致,不需要针对每种数据结构编写特定的遍历逻辑。
  3. 支持多种遍历方式:可以根据需求提供多种迭代器实现,如顺序迭代、逆序迭代、过滤迭代等,以满足不同的业务场景。
  4. 灵活性与可扩展性:可以在不修改原有类库的基础上添加新的迭代器,增强了系统的灵活性和可扩展性。
  5. 遵循单一职责原则:将数据存储和数据遍历的功能分离,每个类都专注于自己的职责。

缺点:

  1. 增加系统复杂性:对于简单的数据结构或小型项目来说,引入迭代器模式可能会增加系统的复杂性,如果直接使用内置的循环遍历可能更为简单。
  2. 无法直接进行随机访问:标准的迭代器通常只支持按顺序访问,若要支持随机访问则需要额外设计(例如Java中的ListIterator)。
  3. 内存和性能开销:创建迭代器实例会带来一定的内存开销,尤其是对于大型集合而言。此外,某些自定义迭代器的实现可能会导致性能下降,比如在遍历过程中涉及复杂的计算或状态跟踪。
  4. 不符合部分语言特性:对于支持内部迭代的语言(如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();
        }
    }
}