行为型设计模式之迭代器模式

633 阅读4分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第31天,点击查看活动详情

迭代器模式

迭代器模式(Iterator Pattern)又称为游标模式(Cursor Pattern),属于行为型模式。

它提供一种顺序访问集合容器中的各个对象元素的方法,而又无须暴露集合容器的内部表示。

迭代器模式可以为不同的容器提供一致的遍历行为,而不用关心容器内容元素组成结构。

迭代器模式的本质是抽离集合对象迭代行为到迭代器中,提供一致访问接口。也就是说将集合的遍历行为抽取为单独的迭代器对象。

应用场景

1、访问一个集合对象的内容而无需暴露它的内部表示;

2、为遍历不同的集合结构提供一个统一的访问接口。

3、需要为聚合对象提供多种遍历方式。

主要角色

1.抽象迭代器(Iterator)

抽象迭代器负责定义访问和遍历元素的接口。

2.具体迭代器(Concretelterator)

提供具体的元素遍历行为。

3.抽象容器(Aggregate)

负责定义提供具体迭代器的接口。

4.具体容器(ConcreteAggregate)

创建具体迭代器。

在这里插入图片描述

优缺点

优点:

1.多态迭代:为不同的聚合结构提供一致的遍历接口,即一个迭代接口可以访问不同的集合对象

2.简化集合对象接口:迭代器模式将集合对象本身应该提供的元素迭代接口抽取到了迭代器中,使集合对象无须关心具体迭代行为;

3.元素迭代功能多样化:每个集合对象都可以提供一个或多个不同的迭代器,使的同种元素聚合结构可以有不同的迭代行为;

4.解耦迭代与集合:迭代器模式封装了具体的迭代算法,迭代算法的变化,不会影响到集合对象的架构。

缺点

1.对于比较简单的遍历(数组或者有序列表),使用迭代器方式遍历较为繁琐

2.由于迭代器模式将存储数据和遍历数据的职责分离,增加新的聚合类需要对应增加新的迭代器类,类的个数成对增加,这在一定程度上增加了系统的复杂性。

迭代器模式的基本使用

集合是最常使用的数据类型之一, 是一组装对象的容器。大部分集合使用简单列表存储元素。 但有些集合还会使用栈、 树、 图和其他复杂的数据结构。

无论集合的构成方式如何, 它都必须提供某种访问元素的方式, 便于其他代码使用其中的元素。 集合应提供一种能够遍历元素的方式, 且保证它不会周而复始地访问同一个元素。

创建抽象迭代器

所有迭代器必须实现相同的接口。 如此, 只要有合适的迭代器, 客户端代码就能兼容任何类型的集合或遍历算法。

public interface Iterator<E> {
    E next();
    boolean hasNext();
}

创建具体迭代器

迭代器通常会提供一个获取集合元素的基本方法。 客户端可不断调用该方法直至它不返回任何内容, 这意味着迭代器已经遍历了所有元素。

public class ConcreteIterator<E> implements Iterator<E> {
    private List<E> list;
    private int cursor = 0;

    public ConcreteIterator(List<E> list) {
        this.list = list;
    }

    public E next() {
        System.out.print("当前游标位置:" + cursor+" 对于元素:");
        return this.list.get(this.cursor ++);
    }

    public boolean hasNext() {
        return this.cursor < this.list.size();
    }
}

创建抽象容器

public interface IAggregate<E> {
    boolean add(E element);

    boolean remove(E element);
    Iterator<E> iterator();
}

创建具体容器

public class ConcreteAggregate<E> implements IAggregate<E> {
    private List<E> list = new ArrayList<E>();

    public boolean add(E element) {
        return this.list.add(element);
    }

    public boolean remove(E element) {
        return this.list.remove(element);
    }

    public Iterator<E> iterator() {
        return new ConcreteIterator<E>(this.list);
    }
}

客户端执行

public class Test {
    public static void main(String[] args) {
        // 创建容器对象
        IAggregate<String> aggregate = new ConcreteAggregate<String>();
        // 添加元素
        aggregate.add("A");
        aggregate.add("B");
        aggregate.add("C");
        aggregate.add("D");
        aggregate.add("E");
        aggregate.add("F");
        aggregate.add("G");

        Test.testIterator(aggregate);

        System.out.println("==================================================");

        aggregate.remove("D");
        aggregate.remove("E");
        Test.testIterator(aggregate);
    }

    public static void testIterator(IAggregate<String> aggregate) {
        // 获取容器对象迭代器
        Iterator<String> iterator = aggregate.iterator();
        // 遍历获取元素
        while (iterator.hasNext()) {
            String element = iterator.next();
            System.out.println(element);
        }
    }
}
当前游标位置:0 对于元素:A
当前游标位置:1 对于元素:B
当前游标位置:2 对于元素:C
当前游标位置:3 对于元素:D
当前游标位置:4 对于元素:E
当前游标位置:5 对于元素:F
当前游标位置:6 对于元素:G
==================================================
当前游标位置:0 对于元素:A
当前游标位置:1 对于元素:B
当前游标位置:2 对于元素:C
当前游标位置:3 对于元素:F
当前游标位置:4 对于元素:G