》》Iterator 模式用于在数据集合中按照顺序遍历集合。
--------------------下面的示例程序的作用是将书(Book)放置到书架(BookShelf)中,
并将书的名字按顺序显示出来。
》》示例程序的示意图:
》》示例程序的类图:
》》Aggregate 接口:
package iterator;
/*
* 该接口中声明的方法只有一个-----iterator 方法。该方法会生成一个用于
* 遍历集合的迭代器
*/
public interface Aggregate {
public abstract Iterator iterator();
}
》》Iterator 接口:
package iterator;
/*
* 该接口用于遍历集合中的元素,其作用相当于循环语句中的循环变量
*/
public interface Iterator {
public abstract boolean hasNext(); //判断是否存在下一个元素的hasNext 方法 ,该方法主要用于循环终止条件
public abstract Object next(); //获取下一个元素的 next 方法
}
》》Book 类:
package iterator;
public class Book {
private String name; //书名
public Book(String name){
this.name = name;
}
//获取书的名字
public String getName(){
return name;
}
}
》》BookShelf 类:
package iterator;
public class BookShelf implements Aggregate{
private Book[] books;
private int last = 0; //书架上书的数量
public BookShelf(int maxsize){ //生成 BookShelf 实例时指定 books 数组的大小
this.books = new Book[maxsize];
}
public Book getBookAt(int index){ //获取书架上指定位置的书籍
return books[index];
}
public void appendBook(Book book){ //往书架上添加书籍
this.books[last] = book;
last++;
}
public int getLength(){ //获取书架上目前有多少本书
return last;
}
//获取遍历该书架的 Iterator 实例。当想在外部遍历书架时,就会调用该方法
public Iterator iterator(){
return new BookShelfIterator(this);
}
}
》》BookShelfIterator 类:
package iterator;
public class BookShelfIterator implements Iterator{
private BookShelf bookShelf; //所要遍历的书架
private int index; //表示迭代器当前所指向的书的下标
public BookShelfIterator(BookShelf bookShelf){
this.bookShelf = bookShelf;
this.index = 0;
}
/*
* hasNext () 方法会判断书架中还有没有下一本书,如果有就返回 true ,
* 如果没有就返回 false 。而要知道书架中有没有下一本书,可以通过比较index
* 和书架中书的总册数(bookShelf.getLength())来判断。
*
*/
public boolean hasNext(){
if(index < bookShelf.getLength()){
return true;
}else{
return false;
}
}
/*
* next() 方法会返回迭代器当前所指向的书(Book 的实例),并让迭代器指向下一本书。
*
*/
public Object next(){
Book book = bookShelf.getBookAt(index);
index++;
return book;
}
}
》》Main 类:---------->测试程序
package iterator;
public class Main {
public static void main(String[] args){
BookShelf bookShelf = new BookShelf(4);
bookShelf.appendBook(new Book("Around the World in 80 Days"));
bookShelf.appendBook(new Book("Bible"));
bookShelf.appendBook(new Book("Cinderella"));
bookShelf.appendBook(new Book("Daddy-Long-Legs"));
Iterator it = bookShelf.iterator();
while(it.hasNext()){
Book book = (Book)it.next();
System.out.println(book.getName());
}
}
}
》》运行结果:
--------------------------------------------------------------
《Iterator 模式中的登场角色》
**** Iterator (迭代器)
该角色负责定义按顺序逐个遍历元素的接口(API) 。在示例程序中,由 Iterator
接口扮演这个角色,它定义了 hasNext 和 next 两个方法。其中,hasNext 方法用
于判断是否存在下一个元素, next 方法用于获取该元素。
**** ConcreteIterator (具体的迭代器)
该角色负责实现 Iterator 角色所定义的接口(API)。在示例程序中,
BookShelfIterator 类扮演这个角色。该角色中包含了遍历集合所必需的信息。在示
例程序中,BookShelf 类的实例保存在 bookShelf 字段中,被指向的书的下标保存
在 index 字段中。
**** Aggregate(集合)
该角色负责定义创建 Iterator 角色的接口(API)。这个接口是一个方法,会创建出
“按顺序访问保存在我内部元素的人”。在示例程序中,由Aggregate 接口扮演这个角色,
它里面定义了 iterator 方法。
**** ConcreteAggregate (具体的集合)
该角色负责实现 Aggregate 角色所定义的接口(API) 。它会创建出具体的 Iterator
角色,即 ConcreteIterator 。在示例程序中,由BookShelf 类扮演这个角色,它实现了
iterator 方法。
-------------------------------------------------------------------------
《扩展思路的要点》
1.不管实现如何变化,都可以使用 Iterator
**** 引入 Iterator 后可以将遍历与实现分离开来。
**** 设计模式的作用就是帮助我们编写可复用的类。所谓“可复用”,就是指将类实现为
“组件”,当一个组件发生改变时,不需要对其他的组件进行修改或是只需要很小的
即可应付。
2.难以理解抽象类和接口-------->引入抽象类和接口是为了降低耦合度
**** 如果只是用具体的类来解决问题,很容易导致类之间的强耦合,这些类也难以作为
组件被再次利用。为了弱化类之间的强耦合,进而使得类更加容易作为组件被再次
利用,我们需要 引入抽象类和接口。
3.Aggregate 和 Iterator 的对应
4.容易弄错“下一个”
在Iterator 模式的实现中,next 方法是 “返回当前的元素,并指向下一个元素”
5.还容易弄错“最后一个”
hasNext 可以理解成:“确认接下来是否可以调用 next 方法”的方法就可以了。
6.多个Iterator
“将遍历功能置于 Aggregate 角色之外 ”是 Iterator 模式的一个特征。
7.迭代器种类的多种多样
在示例程序中展示的 Iterator 类只是很简单地从前往后遍历集合。其实,遍历的
方法有是多种多样的。
**** 从最后开始向前遍历
**** 既可以从前向后遍历,也可以从后往前遍历(既有 next 方法也有 previous 方法)
**** 指定下标进行“跳跃式”遍历
8.不需要 deleteIterator
在Java 中,没有被使用的对象实例将会自动删除(垃圾回收机制)。因此,在
Iterator 中不需要与其对应的 deleteIterator 方法 。
------------------------------------------------------------------------------
《相关的设计模式》
**** Visitor 模式
**** Composite 模式
**** Factory Method 模式