迭代器模式(Iterator Pattern)也被称为游标模式(Cursor Pattern),是在 GoF 23 种设计模式中定义了的行为型模式。是一种最简单也最常见的设计模式。
迭代器模式 可以让用户透过特定的接口巡访容器中的每一个元素而不用了解底层的实现。
~
本篇文章内容包括:关于迭代器模式、观察者模式 Demo、模版方法模式的应用(ArrayList/Iterator 中的迭代器模式)
迭代器模式(Iterator Pattern)也被称为游标模式(Cursor Pattern),是在 GoF 23 种设计模式中定义了的行为型模式。是一种最简单也最常见的设计模式。
迭代器模式 可以让用户透过特定的接口巡访容器中的每一个元素而不用了解底层的实现。
迭代器模式 提供一种方法顺序访问一个聚合(指一组对象的组合结构,如:Java中的集合、数组等)对象中各个元素,而又不需暴露该对象的内部表示。迭代器模式的本质:控制访问聚合对象中的元素。其设计意图:无须暴露聚合对象的内部实现,就能够访问到聚合对象中的各个元素。
迭代器模式主要包含以下 4 种角色:
抽象聚合(Aggregate)角色:定义存储、添加、删除聚合元素以及创建迭代器对象的接口。
具体聚合(ConcreteAggregate)角色:实现抽象聚合类,返回一个具体迭代器的实例。
抽象迭代器(Iterator)角色:定义访问和遍历聚合元素的接口,通常包含 hasNext()、next() 等方法。
具体迭代器(Concretelterator)角色:实现抽象迭代器接口中所定义的方法,完成对聚合对象的遍历,记录遍历的当前位置。
迭代器模式优点
迭代器模式缺点
定义一个可以存储学生对象的容器对象,将遍历该容器的功能交由迭代器实现。
Demo 类图如下:
# Student 元素类
public class Student {private String name;private String number;@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", number='" + number + '\'' +'}';}/*** 建造者类构造函数** @param builder Builder*/private Student(Builder builder) {name = builder.name;number = builder.number;}/*** 建造者类*/public static final class Builder {private String name;private String number;public Builder() {}public Builder name(String val) {name = val;return this;}public Builder number(String val) {number = val;return this;}public Student build() {return new Student(this);}}
}
# StudentAggregate 抽象聚合(Aggregate)角色
public interface StudentAggregate {/*** 添加元素* @param student Student*/void addStudent(Student student);/*** 删除元素* @param student Student*/void removeStudent(Student student);/*** 获取迭代器对象* @return StudentIterator*/StudentIterator getStudentIterator();
}
# StudentAggregateImpl 具体聚合(ConcreteAggregate)角色
import java.util.ArrayList;
import java.util.List;public class StudentAggregateImpl implements StudentAggregate {/*** 学生列表*/private final List list = new ArrayList();@Overridepublic void addStudent(Student student) {this.list.add(student);}@Overridepublic void removeStudent(Student student) {this.list.remove(student);}@Overridepublic StudentIterator getStudentIterator() {return new StudentIteratorImpl(list);}}
# StudentIterator 抽象迭代器(Iterator)角色
public interface StudentIterator {/*** 判断是否还有下一个元素* @return boolean*/boolean hasNext();/*** 获取下一个元素* @return Student*/Student next();
}
# StudentIteratorImpl 具体迭代器(Concretelterator)角色
import java.util.List;public class StudentIteratorImpl implements StudentIterator {private final List list;private int position = 0;public StudentIteratorImpl(List list) {this.list = list;}@Overridepublic boolean hasNext() {return position < list.size();}@Overridepublic Student next() {Student currentStudent = list.get(position);position ++;return currentStudent;}
}
public class Client {public static void main(String[] args) {// 抽象聚合类-StudentAggregate 具体聚合类-StudentAggregateImplStudentAggregate studentAggregate = new StudentAggregateImpl();// 建造者模式构造元素studentAggregate.addStudent(new Student.Builder().name("小明").number("1001").build());studentAggregate.addStudent(new Student.Builder().name("小红").number("1002").build());// 通过 具体聚合类 获取 具体迭代器StudentIterator iterator = studentAggregate.getStudentIterator();// 迭代器遍历while (iterator.hasNext()){System.out.println(iterator.next().toString());}}
}
Java 代码中关于 List 的迭代器使用:
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;public class IteratorDemo {public static void main(String[] args) {List list = new ArrayList<>();list.add("AA");list.add("BB");list.add("CC");// list.iterator() 方法返回的肯定是 Iterator 接口的子实现类对象Iterator iterator = list.iterator();while (iterator.hasNext()) {System.out.println(iterator.next());}}
}
其中,List-抽象聚合类、ArrayList-具体的聚合类、Iterator-抽象迭代器、list.iterator()
返回的是实现了 Iterator
接口的具体迭代器对象。
# ArrayList 的源码对于迭代器部分的实现:
public class ArrayList extends AbstractList implements List, RandomAccess, Cloneable, Serializable {public Iterator iterator() {return new ArrayList.Itr();}private class Itr implements Iterator {// 下一个要返回元素的索引int cursor; // 上一个返回元素的索引int lastRet = -1; int expectedModCount = modCount;Itr() {}//判断是否还有元素public boolean hasNext() {return cursor != size;}//获取下一个元素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];}...}
}
可以看到:在 iterator
方法中返回了一个实例化的 Iterator
对象。Itr 是一个内部类,它实现了 Iterator
接口并重写了其中的抽象方法。
// List 集成自 Collection
public interface List extends Collection// Collection 继承自 Iterable
public interface Collection extends Iterable
Ps:当我们在使用 Java 开发的时候,想使用迭代器模式的话,只要让我们自己定义的容器类实现 java.util.Iterable
并实现其中的 iterator() 方法使其返回一个 java.util.Iterator
的实现类就可以了。