上一篇介紹了Simple factor pattern, 今天來介紹一下Iterator。
Iterator,中譯迭代。簡單來說,Iterator 就是對集合裡的每個原素進行處理。
如果你在演算法裡有看到「對XX裡的每個YY…」,那你通常都會用到這個pattern。
for each y in x
do blablabla
end for;
Iterator pattern 是對集合裡的每個原素(element)進行處理,因此他的構成的成份,第一個就是「集合」這個元件。(好像是廢話呢…) 第二個元件,是通常會有個指標,來記錄目前處理到那一個原素;第三個元件是需要處理一些事。程式在處理完那些事後,就將指標移往下一個原素。 第四個,就是這一段程式碼裡,通常會需要有個判斷式,來判斷是不是所有有東西都已經處理過。
接下來看一下實際例子。
假設我一個書櫃(BookShelf
),有書櫃就有書(BookVo
)…這次書是我們要講的重點了。
於是程式碼Iterator interface會是像這個樣子:
public interface Iterator<E> {
boolean hasNext();
E next();
}
由於我們要依次處理的是書(BookVo
);所以實作這個interface的程式碼會是這個樣子。
private class BookVoIterator implements Iterator<BookVo> {
private int index = -1;
@Override
public boolean hasNext() {
return index < size - 1;
}
@Override
public BookVo next() {
index++;
return bookVos[index];
}
}
next()
是裡含了二個元件:第一個是指標(這不是C語言中的指標)的移動。第二個是「處理」;它除了在每次iterate時會將指標移到下一個原素之外,還做了一個動作:生出BookVo
,並加以回傳。
hasNext()
是第四個元件,它負責判斷是否還有下一個需要處理的原素,少了這元件,就會淪落成無窮迴圈(雖然有時需要這麼做…)。
那第一個元件呢? 再下面。
public class BookShelf implements Iterable<BookVo> {
private BookVo[] bookVos;
public BookVo findBook(String bookName) {
for (Iterator<BookVo> it = iterator(); it.hasNext();) {
BookVo bookVo = it.next();
if (bookVo.getName().equals(bookName)) {
return bookVo;
}
}
return null;
}
}
我們之前提到第一個元件,就是集合。 在這個例子裡,書的集合就是書櫃(BookShelf
)。 先暫時別管Iteratorable這個interface; 這個interface現在還不是重點。 重要的是iterator的使用方式; 主要client端method(就是使用端、呼叫的程式)是findBook
。顧名思義,就是從書名找書;怎麼找?一本一本找。 對書櫃裡的每一本書進行比對,直找到書名相同的書為止。 有注意到嗎? 「對XX裡的每個YY…」,我又用到這樣的描述了…。
總而言之Iterator的class diagram。
要怎麼用?
Java 1.5 有提供了enhance for loop的語法。 我還蠻常用這個。 主要是因為我認為電腦就是該執行重覆的工作;反正就是有一堆工作叫電腦去做,讓電腦針對所有工作任務裡的每一個工作(對XX裡的每個YY…),一項一項執行…。 在for each裡的集合,必需要實作Iterable interface。 因此,上面的findBook
可改寫borrowBook
:
public BookVo borrowBook(String bookName) {
ShelfFactory boFactory = context.getBean(ShelfFactory.class);
BookShelf bookShelf = boFactory.getBookShelf("POMO");
for (BookVo book : bookShelf) {
if(book.getName().equals(bookName)){
return book;
}
}
return null;
}
可以看到for (BookVo book : bookShelf)
的寫法要比單純的for迴圈的方式,要更簡單了一些。
題外話,Java是自1.5後才提供enhance foreach。 不過還記得我們之前有提過,Design pattern是無關乎程式語言的。 即始Java 1.5才提供foreach這種語法,早在更早之前,就有其他的Iteratgr介面可供使用。
結論
這一篇是使用與Simple factory相同的例子做示範,簡單介紹一下iterator pattern。 Iterator不只是可以next
,也有可以previous
、也可以直接first
或last
。 沒錯,就是我們一般在網頁上最常看到的paging。
大家是否有注意到,我們常用的jdbc ResultSet
也有相同的味道喔!
沒有留言 :
張貼留言