设计模式之迭代器模式

定义

提供一种方法顺序访问一个聚合对象中的各个元素,而又不需暴露该对象的内部表示。如我们日常生活中的快递,不管内部是什么物品,
都会被统一打包,我们不需要关心里面是什么,只需要按照目的地发送即可。

结构

  • Iterator,迭代器接口,定义访问和遍历元素的方法。
  • ConcreteIterator,具体迭代器实现对象,实现对聚合对象的遍历。
  • Aggregate,聚合对象接口,定义创建迭代器对象的方法。
  • ConcreteAggregate,具体聚合对象,实现创建相应的迭代器对象。

简单实现

迭代器接口

public interface Iterator {

  boolean hasNext();

  Object next();
}

具体迭代器

public class ConcreteIterator implements Iterator {

  private ConcreteAggreate aggreate;
  private int cursor = 0;

  public ConcreteIterator(ConcreteAggreate aggreate) {
    this.aggreate = aggreate;
  }

  @Override
  public boolean hasNext() {
    return cursor < aggreate.size();
  }

  @Override
  public Object next() {
    return aggreate.get(cursor++);
  }
}

聚合对象接口

public interface Aggregate {

  Iterator createIterator();
}

具体聚合对象的实现

public class ConcreteAggreate implements Aggregate {

  private String[] data;

  public ConcreteAggreate(String[] data) {
    this.data = data;
  }

  public int size() {
    return data.length;
  }

  public String get(int index) {
    if (index < 0 || index >= data.length) {
      return null;
    }
    return data[index];
  }

  @Override
  public Iterator createIterator() {
    return new ConcreteIterator(this);
  }
}

客户端

public class Client {

  public static void main(String[] args) {
    ConcreteAggreate aggreate = new ConcreteAggreate(new String[]{"a","b","c"});
    Iterator iterator = aggreate.createIterator();
    while (iterator.hasNext()) {
      System.out.println(iterator.next());
    }
  }

}

输出为

a
b
c

java中已经提供了 Iterator 接口和 Iterable 接口来实现迭代器模式。

import java.util.Iterator;

public class ConcreteIterator implements Iterator {

  private ConcreteAggreate aggreate;
  private int cursor = 0;

  public ConcreteIterator(ConcreteAggreate aggreate) {
    this.aggreate = aggreate;
  }

  @Override
  public boolean hasNext() {
    return cursor < aggreate.size();
  }

  @Override
  public Object next() {
    return aggreate.get(cursor++);
  }
}

具体聚合对象

public class ConcreteAggreate implements Iterable {

  private String[] data;

  public ConcreteAggreate(String[] data) {
    this.data = data;
  }

  public int size() {
    return data.length;
  }

  public String get(int index) {
    if (index < 0 || index >= data.length) {
      return null;
    }
    return data[index];
  }

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

客户端

import java.util.Iterator;

public class Client {

  public static void main(String[] args) {
    ConcreteAggreate aggreate = new ConcreteAggreate(new String[]{"a", "b", "c"});
    Iterator iterator = aggreate.iterator();
    while (iterator.hasNext()) {
      System.out.println(iterator.next());
    }
  }

}

迭代器模式在JDK的实现

JDK中ArrayList

public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable {

    public Iterator<E> iterator() {
        return new Itr();
    }
/**
     * An optimized version of AbstractList.Itr
     */
    private class Itr implements Iterator<E> {
        int cursor;       // index of next element to return
        int lastRet = -1; // index of last element returned; -1 if no such
        int expectedModCount = modCount;

        // prevent creating a synthetic constructor
        Itr() {}

        public boolean hasNext() {
            return cursor != size;
        }

        @SuppressWarnings("unchecked")
        public E next() {
            checkForComodification();
            int i = cursor;
            if (i >= size)
                throw new NoSuchElementException();
            Object[] elementData = ArrayList.this.elementData;
            if (i >= elementData.length)
                throw new ConcurrentModificationException();
            cursor = i + 1;
            return (E) elementData[lastRet = i];
        }
    }
}

JDK中的ArrayList,LinkedList,HashSet等都实现了迭代器模式。

总结

优点

  1. 更好的封装性,访问一个聚合对象的内容而无需暴露该聚合对象的内部表示。
  2. 支持以不同的方式来遍历聚合对象。

缺点

  1. 增加新的聚合类需要增加对应的迭代器类。

本质

迭代器模式的本质是控制访问聚合对象中的元素。

使用场景

  1. 当我们想访问一个聚合对象的内容而又不想暴露内部表示时,可以使用迭代器模式,实际开发中我们一般使用java自身提供的迭代器实现。

参考

大战设计模式【12】—— 迭代器模式
设计模式的征途—21.迭代器(Iterator)模式
设计模式(十七)——迭代器模式(ArrayList 集合应用源码分析)
迭代器模式(详解版)
研磨设计模式-书籍

posted @ 2021-08-22 20:53  strongmore  阅读(54)  评论(0编辑  收藏  举报