迭代器模式

简介

Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation.
提供一种顺序访问聚集/容器对象元素的方法,而又无须暴露聚集内部表象。

迭代器模式(Iterator Pattern) 又称为 游标(Cursor)模式,是对象的行为模式。

迭代器模式 可以顺序地访问一个聚集中的元素,而又不会暴露聚集内部表象。也即 迭代器模式 可以为不同的容器提供一致的遍历行为,而不用关心容器内容元素组成结构。

迭代器模式 本质:抽离聚集对象迭代行为到迭代器种,提供一致访问接口

主要解决

我们把多个对象聚在一起形成的总体称之为聚集(Aggregate),聚集对象是能够包容一组对象的容器对象。不同的聚集其内部元素的聚合结构可能不同,而 迭代器模式 屏蔽了内部元素获取细节,为外部提供一致的元素访问行为,解耦了元素迭代与集合对象间的耦合,并且通过提供不同的迭代器,可以为同个聚集对象提供不同顺序的元素访问行为,扩展了聚集对象元素迭代功能,符合 开闭原则

优缺点

优点

  • 多态迭代:为不同的聚合结构提供一致的遍历接口,即一个迭代接口可以访问不同的聚集对象;
  • 简化聚集对象接口:迭代器模式 将聚集对象本身应该提供的元素迭代接口抽取到了迭代器中,使聚集对象无须关心具体迭代行为;
  • 元素迭代功能多样化:每个聚集对象都可以提供一个或多个不同的迭代器,使的同种元素聚合结构可以有不同的迭代行为;
  • 解耦迭代与聚集:迭代器模式 封装了具体的迭代算法,迭代算法的变化,不会影响到聚集对象的架构;

缺点

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

使用场景

  • 遍历一个容器对象时;

模式讲解

首先来看下 迭代器模式 的通用 UML 类图:

迭代器模式_第1张图片
迭代器模式

从 UML 类图中,我们可以看到,迭代器模式 主要包含三种角色:

  • 抽象迭代器(Iterator):抽象迭代器负责定义访问和遍历元素的接口;
  • 具体迭代器(ConcreteIterator):提供具体的元素遍历行为;
  • 抽象容器(Aggregate):负责定义提供具体迭代器的接口;
  • 具体容器(ConcreteAggregate):创建具体迭代器;

以下是 迭代器模式 的通用代码:

class Client {
    public static void main(String[] args) {
        //来一个容器对象
        IAggregate aggregate = new ConcreteAggregate<>();
        //添加元素
        aggregate.add("one");
        aggregate.add("two");
        aggregate.add("three");
        //获取容器对象迭代器
        Iterator iterator = aggregate.iterator();
        //遍历
        while (iterator.hasNext()) {
            String element = iterator.next();
            System.out.println(element);
        }

    }

    //抽象迭代器
    interface Iterator {
        E next();

        boolean hasNext();
    }

    //具体迭代器
    static class ConcreteIterator implements Iterator {
        private List mList;
        private int mCursor = 0;

        public ConcreteIterator(List list) {
            this.mList = list;
        }

        @Override
        public E next() {
            return this.mList.get(this.mCursor++);
        }

        @Override
        public boolean hasNext() {
            return this.mCursor < this.mList.size();
        }
    }

    //抽象容器
    interface IAggregate {
        boolean add(E element);

        boolean remove(E element);

        Iterator iterator();
    }

    //具体容器
    static class ConcreteAggregate implements IAggregate {
        private List mList = new ArrayList<>();

        @Override
        public boolean add(E element) {
            return this.mList.add(element);
        }

        @Override
        public boolean remove(E element) {
            return this.mList.remove(element);
        }

        @Override
        public Iterator iterator() {
            return new ConcreteIterator(this.mList);
        }
    }
}

通过上面的代码,我们可以更清楚地了解到 迭代器模式 的作用就是将聚集对象的迭代行为抽取到迭代器中,解耦了元素迭代与聚集对象之间的耦合,使得不同的聚集对象对外都能提供一致的迭代行为。

:认真思考以下 迭代器模式 和 组合模式,其实这两者似乎存在一定的相似性。组合模式 解决的是统一树形结构各层次访问接口,迭代器模式 解决的是统一各聚集对象元素遍历接口。虽然他们的适配场景不同,但核心理念是相通的。

你可能感兴趣的:(迭代器模式)