1. Iterator模式
Java語言爲了把arr數組的內容全部表示出來,使用for語句按照下面的方法書寫。
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
這裏通過變量i的遞增來達到數組遍歷。
我們把變量i的動作抽象化,一般化後的設計模式叫做迭代模式(Iterator Pattern)。
迭代模式,就是把某種對象大量集中到一起,按照順序進行全體掃描處理的一種設計模式。
2.迭代模式的例子
使用到的類和接口一覽:
Aggregate: 表示集合的接口
Iterator: 執行遍歷掃描的接口
Book: 表示書的類
BookShelf: 表示書架的類
BookShelfIterator: 遍歷書架的類
Main: 動作測試用的類
public interface Aggregate {
public abstract Iterator iterator();
}
public interface Iterator {
public abstract boolean hasNext();
public abstract Object next();
}
public class Book {
private String name;
public Book(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
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;
last++;
}
public int getLength() {
return last;
}
public Iterator iterator() {
return new BookShelfIterator(this);
}
}
public class BookShelfIterator implements Iterator {
private BookShelf bookShelf;
private int index;
public BookShelfIterator(BookShelf bookShelf) {
this.bookShelf = bookShelf;
this.index = 0;
}
public boolean hasNext() {
if (index < bookShelf.getLength()) {
return true;
} else {
return false;
}
}
public Object next() {
Book book = bookShelf.getBookAt(index);
index++;
return book;
}
}
import java.util.*;
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());
}
}
}
3.迭代模式的登場角色
(1) Iterator的角色
擔當確定順序掃描各個元素用的接口API。next取得下一個元素,hasNext判斷下一個元素是否存在。
(2)ConcreteIterator(具體的循環子)的角色
BookShelfIterator類擔當具體的實現類。
(3)Aggregate(集合)的角色
生成Iterator角色的接口API。
(4)ConcreteAggregate(具體的集合體)的角色
BookShelf擔當具體的實現類。
4.擴展你思路的提示
(1)無論實作怎樣,都可以使用Iterator。
爲什麼要考慮Iterator模式這樣麻煩的東西呢,for循環不是更直接嗎。一個很大的理由是,通過使用Iterator,使程序和具體實現分離的情況下的遍歷變得可能。不再依賴BookShelf的實作。
while (it.hasNext()) {
Book book = (Book)it.next();
System.out.println(book.getName());
}
(2)不擅長使用抽象類和接口
就算不使用Aggregate類,而直接使用具體類BookShelf,不也能實現嗎。
是可以,但是,一旦使用了具體類,類之間的結合變得更加緊密,把各個類作爲零件重複使用也變得困難。因此才導入抽象類和接口。
同理,也不直接使用BookShelfIterator。
當具體類發生變化的使用,調用它的代碼基本上不用做修改。
每個具體的集合對應一個具體的迭代類,當集合類的實現發生變化是,僅需修改具體迭代類即可。
(3)『下一個』容易引起誤會
其實next相當於 returnCurrentElementAndAdvanceToNextPosition,返回當前元素,並且把指針移向下一個元素。
(4)多個Iterator
一個具體集合類,可以有多個具體迭代類。
(5)迭代的種類很多
迭代的種類不限於順序掃描。
a)從最後尾開始逆向掃描
b)順序掃描,逆向掃描兩個方向 next,privious
c)指定元素索引,直接跳轉
5.相關模式
(1)Visitor模式
針對所有元素,循環做同樣的處理。
(2)Composite模式
遞歸的結構。
(3)Factory Method模式
迭代子實例的做成,可以通過工廠方法來完成。