迭代器模式(Iterator),提供一种方法顺序访问一个聚合对象中的各种元素,而又不暴露该对象的内部表示。

迭代器模式是针对集合对象而生的,对于集合对象而言,肯定会涉及到对集合的添加和删除操作,同时也肯定支持遍历集合元素的操作,我们此时可以把遍历操作放在集合对象中,但这样的话,集合对象既承担太多的责任了,面向对象设计原则中有一条就是单一职责原则,所有我们要尽可能地分离这些职责,用不同的类取承担不同的责任,迭代器模式就是用迭代器类来承担遍历集合的职责。

  • 意图:提供一种方法顺序访问一个聚合对象中各个元素, 而又无须暴露该对象的内部表示。
  • 主要解决:不同的方式来遍历整个整合对象。
  • 何时使用:遍历一个聚合对象。
  • 如何解决:把在元素之间游走的责任交给迭代器,而不是聚合对象。
  • 关键代码:定义接口:hasNext, next。

迭代器模式 - 图1

1.3 Java代码实现

将书(Book)放到书架(BookShelf)中,并将书名按顺序显示。
Aggregate 接口
所要便利的集合的接口。实现了该接口的类将成为一个可以保存多个元素的集合,类似数组。

  1. public interface Aggregate{
  2. public abstract Iterator iterator();
  3. }

Aggregate接口中声明的方法为iterator,作用为生成一个用于遍历的迭代器。
Iterator 接口
作用为遍历集合中元素,相当于循环语句中的循环变量(for(int i =0 ;i<arr.lenth;i++),具体实现一个顺序遍历的迭代器。

  1. public interface Iterator{
  2. public abstract boolean hasNext();
  3. public abstract Object next();
  4. }

hasNext() 方法判断是否存在下一个,next()方法获取下一个元素。
特殊说明下,next方法在获取元素的同时,要将计数器向下一个元素的计数加一。获取的是当前元素,并指向下一个元素。
Book类
普通类,书名field 获取书名的getName()方法。构造函数初始化书名。

  1. public class Book{
  2. private String name ;
  3. public Book(String name){
  4. this.name=name;
  5. }
  6. public String getName(){
  7. return name;
  8. }
  9. }

BookShelf 类
书架类,作为存放书的集合类,实现Aggregate接口。实现了Aggregate接口的iterator方法。

  1. public class BookShelf implements Aggregate {
  2. private List<Book> books;
  3. public BookShelf() {
  4. this.books = new ArrayList<Book>();
  5. }
  6. public Book getBookAt(int index) {
  7. return books.get(index);
  8. }
  9. public void appendBook(Book book) {
  10. books.add(book);
  11. }
  12. public int getLength() {
  13. return books.size();
  14. }
  15. // 返回iterator对象
  16. public Iterator iterator() {
  17. return new BookShelfIterator(this);
  18. }
  19. }

主要点在iterator方法,方法返回了遍历书架时要用的BookShelfIterator类作为书架的迭代器。当外部要遍历书架时会调用该方法。
BookShelfIterator类

  1. public class BookShelfIterator implements Iterator {
  2. private BookShelf bookShelf;
  3. private int index;
  4. public BookShelfIterator(BookShelf bookShelf) {
  5. this.bookShelf = bookShelf;
  6. this.index = 0;
  7. }
  8. public boolean hasNext() {
  9. if (index < bookShelf.getLength()) {
  10. return true;
  11. } else {
  12. return false;
  13. }
  14. }
  15. public Object next() {
  16. Book book = bookShelf.getBookAt(index);
  17. index++;
  18. return book;
  19. }
  20. }

作为一个迭代器,要实现Iterator接口。index为迭代器当前所指向的下标。
hasNext判断还有没有下一本。通过下标和总数比较判断。
next获取当前书,并指向下一个。

测试类:

  1. public class Main {
  2. public static void main(String[] args) {
  3. BookShelf bookShelf = new BookShelf();
  4. bookShelf.appendBook(new Book("Around the World in 80 Days"));
  5. bookShelf.appendBook(new Book("Bible"));
  6. bookShelf.appendBook(new Book("Cinderella"));
  7. bookShelf.appendBook(new Book("Daddy-Long-Legs"));
  8. Iterator it = bookShelf.iterator();
  9. while (it.hasNext()) {
  10. Book book = (Book) it.next();
  11. System.out.println(book.getName());
  12. }
  13. }
  14. }
  15. 控制台:
  16. ----------------------------------
  17. Around the World in 80 Days
  18. Bible
  19. Cinderella
  20. Daddy-Long-Legs
  21. ----------------------------------

Iterator模式中各角色的作用:
Iterator(迭代器):该角色责任定义按顺序逐个遍历元素的接口。程序中,由Iterator接口扮演,定义了hasNext和next两个方法。
Concretelterator(具体的迭代器):角色负责实现Iterator角色所定义的接口.该角色包含了遍历集合所必须的信息。
Aggregate(集合):该角色负责定义创建Iterator角色的接口。这个接口是一个方法会创建出一个,按照顺序访问保存在我内部元素的人。
ConcreteAggregate(具体集合):该角色负责实现Aggregate角色所定义的接口。他会创建出具体的Iterator角色,也就是ConcreteIterator,也就是实例中的BookShelf。