Iterator(迭代器)模式
-
我们在日常开发中避免不了会使用各种容器,容器内存放大量的同类型的对象,比如Java中的ArrayList、LinkedList、HashMap等,这几种的遍历方法都是不一样的。Iterator模式为所有容器提供了一个统一的接口,在屏蔽容器的细节的情况下实现对容器内对象的遍历。
-
优点
- 可以实现不同容器但是遍历的使用方式相同,使编写出来的程序更具有一般性和重用
- 在屏蔽容器的细节的情况下实现对容器内对象的遍历
- 支持在一个容器中创建多个不同的迭代器,以实现不同的遍历功能,例如,向后遍历、向前遍历、“跳跃式”遍历等各种实际需要遍历方式
- 由于遍历状态是保存在每一个迭代器对象中、因此对于同一个容器对象可以同时进行多个遍历
- Java中没有被使用的迭代器对象实例将被自动GC,不用手动删除
-
缺点
- 由于存储数据和便利数据的职责分离,增加新的容器(集合)类需要对应增加新的迭代器类,类的个数成对增加,增加了系统的复杂性
-
下面介绍一下Iterator模式的组成部分,先看一下Iterator模式的类图,进行一下总体的了解
UML类图中符号的含义可以参考UML类图中符号的含义
-
Iterator(迭代器)
负责定义迭代器遍历方法的接口,例如hasNext()、next()等
-
ConcreteIterator(迭代器实现)
负责实现Iterator接口内的功能,该对象内会存有遍历时的索引等相关字段
-
Aggregate(集合/容器)
负责定义集合/容器内方法的接口,包括遍历时调用的方法iterator等
-
ConcreteAggregate(集合的实现)
负责实现Aggregate接口内的功能,并且创建Iterator实例对象及实现iterator方法
-
-
接下来以一个案例介绍一下Iterator模式的实现
-
定义Iterator接口
public interface Iterator { public abstract boolean hasNext(); public abstract Object next(); }
-
定义Aggregate接口
public interface Aggregate { public abstract Iterator iterator(); }
-
创建Book类
public class Book{ private String name; public Book(String name){ this.name = name; } public String getName(){ return name; } }
-
创建BookShelf集合类,并实现Aggregate接口
public class BookShelf implements Aggregate { private Book[] books; private int last = 0; public BookShelf(int maxSize){ this.books = new Book[maxSize]; } public Book getBookAt(int index){ return books[index]; } public void appendBook(Book book){ this.books[last++] = book; } public int getLength(){ return last; } @Override public Iterator iterator() { return new BookShelfIterator(this); } }
-
创建BookShelfIterator类,并实现Iterator接口
public class BookShelfIterator implements Iterator { private BookShelf bookShelf; private int index; public BookShelfIterator(BookShelf bookShelf){ this.bookShelf = bookShelf; this.index = 0; } @Override public boolean hasNext() { return index < bookShelf.getLength(); } @Override public Object next() { return bookShelf.getBookAt(index++); } }
-
创建Main类进行测试
public class Main{ public static void main(String[] args){ BookShelf bookShelf = new BookShelf(4); bookShelf.addendBook(new Book("A")); bookShelf.addendBook(new Book("B")); bookShelf.addendBook(new Book("C")); bookShelf.addendBook(new Book("D")); Iterator it = bookShelf.iterator(); while(it.hasNext()){ System.out.println((Book)it.next().getName()); } } }
-
-
总结
本文讲述了迭代器模式,其实就是换一种代码结构实现简单的for循环功能,通过这种复杂的代码结构将元素遍历和实现分离开来,我们可以向容器里增减元素而不影响旧代码访问容器里的元素,代码里采用面向接口编程,创建对象都是基于接口进行创建,隐藏内部实现过程,整个过程体现了高内聚低耦合的思想。实际生产中,如果是简单的功能,我们不用采用这么复杂的代码结构,这增加系统复杂度。如果是复杂的功能,同时考虑到以后的易维护,易扩展,类似这种遍历行为可以采用迭代器模式实现。
-
参考链接
《图解设计模式》
https://baijiahao.baidu.com/s?id=1667082812675833591&wfr=spider&for=pc
https://www.iteye.com/blog/chenjumin-630370