设计模式-迭代器

  1. 意图
  2. 例子
  3. 适用性
  4. 结构
  5. 协作
  6. 效果

意图

提供一种方法顺序访问一个聚合对象中各个元素 , 而又不需暴露该对象的内部表示。

例子

熟悉java就应该知道,Iterator模式这个在java中用的非常广泛。

public interface Collection {
void add(Object item);
int size();
}

接下来使用ArrayList
public class ArrayList implements Collection {
Object[] arr = new Object[10];
private int index = 0;

public void add(Object item) {
if (index == arr.lenth) {
Object[] newArr = new Object[arr.length * 2];
System.arraycopy(arr, 0, newArr, 0, arr.length);
arr = newArr;
}
arr[index] = item;
index++;
}

public int size() {
return index;
}
}

上面是一个普通ArrayList下的构建,还不具备迭代器,只能使用索引下标来进行迭代。
public interface Collection<E> {
void add(E item);
int size();
Iterator iterator();
}

这里建立迭代器的接口
public interface Iterator<E> {
boolean hasNext();
E next();
}

最后让ArrayList实现
public class ArrayList<E> implements Collection<E> {
E[] arr = (E[])new Object[10];
private int index = 0;

public void add(E item) {
if (index == arr.lenth) {
E[] newArr = (E[])new Object[arr.length * 2];
System.arraycopy(arr, 0, newArr, 0, arr.length);
arr = newArr;
}
arr[index] = item;
index++;
}

public int size() {
return index;
}

public Iterator<E> iterator() {
return new ArrayListIterator();
}

private class ArrayListIterator implements Iterator<E> {
private int currentIndex = 0;

public boolean hasNext() {
if (currentIndex >= index) return false;
return true;
}

public E next() {
E item = (E)arr[currentIndex];
currentIndex++;
return item;
}
}
}

此时使用新ArrayList中的Iterator,构建一个迭代器。
public class Main {
public static void main(String[] args) {
Collection<String> list = new ArrayList<>();
Iterator iterator = list.iterator();
while(iterator.hasNext()) {
String data = iterator.next();
}
}
}

适用性

  1. 访问一个聚合对象的内容而无需暴露它的内部表示。
  2. 支持对聚合对象的多种遍历。
  3. 为遍历不同的聚合结构提供一个统一的接口 (即, 支持多态迭代)。

结构

github

协作

ConcreteIterator跟踪聚合中的当前对象,并能够计算出待遍历的后继对象。

效果

迭代器模式有三个重要的作用:

  1. 它支持以不同的方式遍历一个聚合
    复杂的聚合可用多种方式进行遍历。例如 , 代码生成和语义检查要遍历语法分析树。代码生成可以按中序或者按前序来遍历语法分析树。迭代器模式使得改变遍历算法变得很容易 : 仅需用一个不同的迭代器的实例代替原先的实例即可。 你也可以自己定义迭代器的子类以支持新的遍历。
  2. 迭代器简化了聚合的接口
    有了迭代器的遍历接口,聚合本身就不再需要类似的遍历接口了。这样就简化了聚合的接口。
  3. 在同一个聚合上可以有多个遍历
    每个迭代器保持它自己的遍历状态。因此你可以同时进行多个遍历。