Iterator Pattern (指位器/迭代器模式)

前言

如果你希望印出一個整數陣列裡所有的內容的話, 你會用下列的程式碼來完成:
類似這樣子存取整個陣列內容的程式片段使用得非常頻繁, 其中你有一個管理 100 個元素的容器 data, 有一個負責指向目前存取位置的指位器 i, i=0 是把指位器初始化, i<100 是在測試目前的指位器是不是合法的, i++ 是將指位器移到容器中下一個元素上。

在物件導向的程式中除了單純的陣列容器之外, 我們常常使用很多不同的容器物件 (例如: 串列,雙向串列,佇列,堆疊,樹等等), 各種容器物件裡組織和儲存物件的方法都不一樣, 但是一旦希望將容器中所有的物件一一取出時, 我們都可以運用類似上面陣列範例的模型來操作容器物件。

例如:

請注意: hasNext() 這個界面函式的功能比較容易讓人產生混淆, 實際上是指測試一下是否可以執行 next() 這個界面來取得目前的指位器所指到的資料。

範例:Book-BookShelf-BookShelfIterator

類別圖:

source codes

Iterator Pattern

上面的範例並不是一個一般化的範例, 下面我們利用 Object, Aggreate, 及 Iterator 三個抽象的類別來定義比較一般化的 Iterator pattern。

範例:Object Aggregate-Iterator Book-BookShelf-BookShelfIterator

類別圖:

source codes

注意事項:

如果一開始我們不採用類似指位器這樣的模型來設計的話, 我們也可以考慮把 hasNext() 和 next() 這兩個界面函式設計在 BookShelf 類別中, 功能看起來也很合理, 資料的存取也很順暢, 但是有一個功能是沒有辦法達到的, 就是在演算法中沒有辦法同時多次尋訪這個 BookShelf 物件中的書籍, 例如下面的演算法就無法實作:
取下書架上每一本書
   請比較該書和所有書架上其它的書籍的作者是否相同
而使用 Iterator Pattern 就可以很輕鬆地實作上面的演算法。

在上面程式碼中 BookShelf 類別提供 getBookAt() 及 getLength() 界面給 BookShelfIterator 類別使用, 在使用 C++ 實作的時候, 有的時候如果 BookShelfIterator 需要存取的私有資料太多的話, 也可以考量使用 friend class 來實作, 在資料存取的便利性和封裝性當中必須做一取捨。 (使用 Java 的話就可以考慮在同一個檔案中來實作這兩個類別)

C++ 程式設計課程 首頁

製作日期: 5/03/2001 by 丁培毅 (Pei-yih Ting)
E-mail: pyting@cs.ntou.edu.tw TEL: 02 24622192x6615
海洋大學 理工學院 資訊科學系