Iterator (迭代器)模式

2021-09-13 13:51:05 字數 4252 閱讀 8149

1.1 iterator 模式

iterator 模式用於在資料集合中按照順序遍歷集合。單詞 iterate 有反覆做某件事情的醫生,漢語稱為「迭代器」。

1.2 示例程式

作用:將書放置到書架(bookshelf)上,並將書的名字按順序顯示出來。

iterator 示例程式類圖

|| aggregate 介面

aggregate 介面是索要遍歷的集合的介面。實現了該介面的類將成為乙個可以儲存多個元素的集合,像陣列一樣。aggregate 有「使聚集」、「集合」的意思。

/**

** describe 生成乙個用於遍歷集合的迭代器

* @author xmc

* @date 2019/3/19 15:11

*/public inte***ce aggregate

在介面中宣告的方法只有乙個 iterator 方法,該方法會生成乙個用於遍歷集合的迭代器。

|| iterator 介面

iterator 介面用於遍歷集合中的元素,其作用相當於迴圈語句中的迴圈變數。下面定義了最簡單的 iterator 介面。

/**

** describe 最簡單的 iterator 介面

*/public inte***ce iterator

宣告兩個方法,判斷是否存在下乙個元素的 hasnext 方法,和獲取下乙個元素的 next 方法。

haxnext 方法返回值是 boolean 型別,當集合中存在下乙個元素時,返回 true,反正不存在,返回 false,即已經遍歷至集合末尾。主要用於迴圈終止條件。

next 方法返回的是乙個泛型元素,同時還隱含著將迭代器移動至下乙個元素的處理。因為 iterator 介面只知道方法名,具體的還是需要檢視 iterator 實現類中的處理。

|| book 類

book 類是表示書的類,做的事情只有一件-通過 getname 方法獲取書的名字。

/**

** describe 書 物件

* @author xmc

*/public class book

public string getname()

}

|| bookshelf 類

bookshelf 類是表示書架的類。需要將該類作為集合進行處理,因此實現了 aggregate 介面。且還實現了 aggregate 介面的 iterator 方法。

/**

** describe 書架類

* @author xmc

*/public class bookshelf implements aggregate

public book getbookat(int index)

// 書架上新增書

books[last] = book;

last++;

}public int getlength()

// 返回迭代器

@override

public iteratoriterator()

public static void main(string args) }}

書架中定義了 books 字段,它是 book 型別的陣列。在構造器中初始化陣列大小。

iterator 方法會生成並返回 bookshelfiterator 類的例項作為 bookshelf 類對應的 iterator。

|| bookshelfiterator 類

用於遍歷書架的 bookshelfiterator 類。

public class bookshelfiterator implements iterator

/***

* describe 判斷是否存在下乙個元素

* @return boolean

*/@override

public boolean hasnext()

/***

* describe 返回下乙個元素的方法

* @return t

*/@override

public book next()

}

因為bookshelfiterator 類需要發揮 iterator 的作用,所以它實現了 iterator 介面。

bookshefl 字段表示 bookshelfiterator 所要遍歷的書架。index 字段表示迭代器當前所指向的書的下標。

hasnext 方法將會判斷書架中還有沒有下一本書,如果有就返回 true,沒有返回 false。可以通過比較 index 和書架中書的總數來判斷。

next 方法會返回迭代器當前所指向的書,並讓迭代器指向下一本書位置。

|| main 類

我們使用 main 類來製作乙個小書架。

public class main }}

while 部分就是 it.hasnext(),只要書架上有書,迴圈就不會停止。

around the world in 80 days

bible

cinderella

daddy-long-legs

1.3 iterator 模式中登場的角色

iterator 模式的類圖

1.4 拓展思路要點

|| 不管實現如何變化,都可以使用 iterator

為什麼一定要引入 iterator 這個複雜的設計模式?如果是陣列,直接 for 迴圈進行遍歷不就可以了麼?為什麼要在集合之外引入 iterator 這個角色呢?

乙個重要的原因,引入 iterator 後可以將遍歷與實現分離出來。

while (iterator.hasnext())
這裡只使用了 iterator 的 hasnext 和 next 方法,並沒有呼叫 bookshelf 的方法。也就是說,這裡的 while 迴圈並不依賴於 bookshelf 的實現。

如果編寫 bookshelf 的開發人員決定放棄用陣列來管理書本,而使用 arraylist 會怎麼樣?不管 bookshelf 如何變化,只要 bookshelf 的 iterator 方法能正確的返回 iterator 例項,即使不對 while 迴圈做修改,**都可以正常工作。這對 bookshelf 的呼叫者來說真是太方便了。

設計模式的作用就是幫助我們編寫可復用的類。所謂的「可復用」,就是指將類實現為「元件」,當乙個元件發生改變時,不需要對其他的元件進行修改或是只需要很小的修改即可應對。

這樣也就能理解為什麼示例程式中 iterator 方法的返回值不是 bookshefliterator 型別而是 iterator 型別了。這段程式就是要使用 iterator 的方法進行程式設計,而不是 bookshelfiterator 的方法。

|| 難以理解抽象類和介面

難以理解抽象類和介面的人常使用 concreteaggregate 角色和 concreteiterator 角色程式設計,而不使用 aggregate 介面和 iterator 介面,總想用具體的類來解決所有問題。

但是如果只使用具體的類來解決問題,很容易導致類之間的強耦合,這些類也難以作為元件被再次利用。為了弱化類之間的耦合,進而使得類更加容易作為元件被再次利用,我們需要引入抽象類和介面。

「不要只使用具體的類來程式設計,要優先使用抽象類和介面來程式設計」。

|| aggregate 和 iterator 的對應

bookshelfiterator 類知道 bookshelf 類是如何實現的。這樣,我們才知道如何來獲取下一本數的 getbookat 方法。也就是說,如果bookshelf 的實現發生了改變,即 getbookat 方法這個介面(api)發生變化時,我們必須修改 bookshelfiterator 類。

正如 aggregate 和 iterator 這兩個介面是對應的一樣,concreteaggregate 和 concreteiterator 這兩個類也是對應的。

|| 多種 iterator

「將遍歷功能置於 aggregate 角色之外」 是 iterator 模式的乙個特徵,可以根據乙個 concreteaggregate 角色編寫多個 concreteiterator 角色。

在示例程式中展示的 iterator 類只是簡答地從前向後遍歷集合。還可以有其他的遍歷方式。

迭代器模式(Iterator)

迭代器模式 iterator 提供一種方法順序訪問乙個聚合物件中的各種元素,而又不暴露該物件的內部表示。當你需要訪問乙個聚合物件,而且不管這些物件是什麼都需要遍歷的時候,就應該考慮使用迭代器模式。另外,當需要對聚集有多種方式遍歷時,可以考慮去使用迭代器模式。迭代器模式為遍歷不同的聚集結構提供如開始 ...

迭代器模式(Iterator)

1.目的 當需要遍歷 單種方式或多種方式 遍歷乙個組合物件時,使用遍歷模式。該模式類似與將容器的介面進行封裝,不對外直接暴露容器的介面的做法類似。2.ifndef iterator h define iterator h include include using namespace std cla...

Iterator 迭代器模式

現在有乙個集合。其內部元素的儲存方式可能比較複雜。為了讓使用者在不用關心其內部表示的情況下對其元素進行訪問,於是建立了乙個迭代器用於對集合的各個元素進行訪問。為了給使用者提供乙個更友好且強大的介面類,於是對迭代器以組合的形式進行封裝,得到乙個管理類。使用者直接操作該管理類即可得到指定元素,或通過管理...