[設計模式] - No.4 Iterator 模式
Iterator 模式
本系列的文章主要是記錄設計模式的學習過程,圍繞《圖解設計模式》和我自身對於設計模式的理解。在文章中出現的程式碼多為《圖解設計模式》這本書中的程式碼。書中一共包含23個設計模式,這篇文章作為這個系列的第一篇文章。由於《圖解設計模式》這本書內容十分簡單,非常適合入門,如果對於設計模式想要進一步地研究,可以參閱一些其他書籍。
Iterator
模式是一種非常簡單的設計模式,其設計出來的目的就是在不知道類具體內部實現的前提下,對這個類的集合中的元素進行一個一個的訪問。當我們對集合物件增加一種新迭代或者儲存方式的時候,並不需要修改對該集合物件訪問的程式碼,只需要增加對應的迭代器即可。
接下來,我們通過書中的一個例子來簡單的看一下什麼是迭代器模式:
首先,我們宣告一個Book
類,這個類儲存書的一些資訊:
public class Book {
private String bookName;
public Book(String bookName) {
this.bookName = bookName;
}
public String getBookName() {
return bookName;
}
@Override
public String toString () {
return "本書名稱叫 " + this.getBookName();
}
}
接下來,我們宣告一個介面Aggregate.java
,這個介面內部有一個函式,該返回一個迭代器。實現該介面表示將該類宣告為可以遍歷的集合,並可以獲得遍歷該類的迭代器。
import java.util.Iterator;
public interface Aggregate {
Iterator iterator();
}
我們有一個BookShelf
類,並實現上述的介面。其意義為一個書架可以被遍歷,並且我們能夠返回遍歷的迭代器
import java. util.Iterator;
import java.util.List;
public class BookShelf implements Aggregate {
private Book [] books;
private int last;
public BookShelf(int shelfSize){
this.books = new Book[shelfSize];
this.last = 0;
}
public void appendBook(Book book){
this.books[last] = book;
last++;
}
public Book getBookAt(int i ){
return books[i];
}
public int getLength(){
return last;
}
@Override
public Iterator iterator() {
return new BookShelfIterator(this);
}
}
注意到,在最後的iterator()
函式中,我們返回了一個BookShelfIterator
,也就是說,我們按照這個迭代器中實現的方式進行遍歷BookShelf
BookShelfIterator
import java.util.Iterator;
public class BookShelfIterator implements Iterator {
private BookShelf bookShelf;
private int cursor;
public BookShelfIterator(BookShelf bookShelf) {
this.bookShelf = bookShelf;
}
@Override
public Object next() {
Book book = bookShelf.getBookAt(cursor);
cursor++;
return book;
}
@Override
public boolean hasNext() {
return cursor<bookShelf.getLength();
}
}
Main.java
對集合進行遍歷
import java.util.Iterator;
public class Main {
public static void main(String[] args) {
BookShelf bookShelf = new BookShelf(5);
bookShelf.appendBook(new Book("哈利波特"));
bookShelf.appendBook(new Book("設計模式"));
bookShelf.appendBook(new Book("故事會"));
bookShelf.appendBook(new Book("情感分析"));
Iterator iterator = bookShelf.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
}
}
當我們的BookShelf
儲存形式更改,或者我們的遍歷的順序更改時,我們不需要修改集合遍歷這部分程式碼,只需要增加對應的迭代器即可。
上面這段程式碼和《圖解設計模式》中的程式碼幾乎一樣,我在某些細節地方做了修改。同時,在BookShelf
中,我是用的是普通陣列進行儲存的,而沒有使用ArrayList
等容器,是為了讓大家更清晰的看到迭代器模式的工作方式。
一個迭代器模式的類圖如下所示:
-
Aggregate(集合)
該角色負責定義建立
Iterator
角色的介面 -
ConcreteAggregate(具體的集合)
負責實現
Aggregate
角色所定義的介面。在這個例子中,由BookShelf
扮演,他實現了iterator()
的方法,並返回第一個訪問該集合的迭代器 -
Iterator(迭代器)
Iterator
主要負責定義按順序遍歷元素的介面API,例如next()
和hasNext()
等方法 -
ConcreteIterator(具體的迭代器)
實現
Iterator
角色所定義的介面,實現具體的next()
和hasNext()
方法
應用了迭代器設計模式的好處就是,我們不需要知道集合儲存元素的方式,即可對集合進行遍歷。如果以後集合BookShelf
中儲存的陣列改為ArrayList
或者其他的容器型別,我們只需要新增一種新的對應這種儲存方式的迭代器實現即可。