Iterator模式的幾種用法
Iterator模式的幾種用法
在網路上看帖子時發現不少模式的初學者對Iterator模式的理解僅僅停留在從類庫的容器類取得Iterator來遍歷容器中的內容的程度。
因此在這裡寫幾個例子,來加深大家對Iterator模式的理解。
對容器中元素的訪問涉及到3個方面。
1.容器的型別
2.檢索容器內元素的方法
3.對元素的操作
比如說我們有一個表示書店的book_store類。裡面儲存了各種各樣的book類的例項。
book類有name和type兩種屬性。表示書的名字和類別。
因此book_store類內部會用一個容器來儲存book的例項。比如list。
class book
{
public:
string name;
string type;
};
class book_store
{
private:
list<book> m_books;
};
我們現在有這樣一個簡單的應用,那就是輸出所有的書名到螢幕。
那麼我們來看一下在引入Iterator模式前有那幾種實現方法,各有什麼缺點。
1.給book_store類增加一個print_book_name的函式。來實現這個功能。
這樣做的缺點有兩個:
(1).將輸入輸出邏輯和業務物件繫結在一起,導致了今後系統難以變更。
(2).輸出邏輯和內部實現繫結。
比如現在要把輸出到螢幕改成輸出到log檔案的話,那麼就需要修改print_book_name了。
2.給book_store類增加一個get_list函式。然後寫一個print_book類來負責列印書名的列表。這是一個初學者常用的方式。表面上看來似乎兩個類各擔其責,一個表示業務物件一個負責列印。
如果需要列印到log檔案的話,只要新增加一個log_book類,book_store和print_book都不受影響。解決了上面的這個問題。
這樣做的缺點是:
(1).把book_store類的內部實現給暴露出來了,違反了封裝的原則。
如果現在把內部容器型別從list換成了vector的話,就要修改輸出邏輯了。也就是說,要同時改寫print_book類和log_book類。
3.增加一個list和vector類共同的基類/介面,比如I_container。然後給book_store類增加一個get_books函式,返回I_container。
這在一定程度上解決了上面的問題。但是並不徹底。應為還是暴露了內部的實現,只不過從list上升到了I_container。
· 如果現在系統發生了變化,book_store不再在本地儲存books了,而是需要透過網路取得的話,print_book和log_book就無法對應了。
· 另一個限制是,我需要一個新的機能,那就是列印所有type為”烹飪書”的機能的話,就需要一個print_cook_book類了,而這裡邊的格式化程式碼和輸出程式碼和print_book是相同的。重複程式碼是維護的噩夢。
接下來我們看一下Iterator模式如何解決以上的這些問題。
首先,我們引入一個I_iterator的Interface。
然後建立一個I_iterator的實現類all_book_iterator。這個類可以迭代book_store中的所有book。
接下來建立一個print_book類,從I_iterator中取得每一個book,然後列印到螢幕。
下面我們看一下如何對應上面的這些需求變更。
1.要求輸出到log檔案
追加一個log_book類,其他都類都不需要改變。
2.將內部容器從list變成vector。
修改iterator中的相關程式碼。Iterator的使用者不會受到影響。
3.從網路取得資料。
修改iterator中的相關程式碼。Iterator的使用者不會受到影響。
4.按照type檢索
在iterator中新增一個type的屬性,或者是構造一個新的type_search_iterator。
在iterator中把不符合檢索條件的book過濾掉。
5.按照某一特定順序輸出book名到螢幕,或是log檔案。
實現一個按該順序輸出的iterator。
6.以同樣的方式列印cd_store。
實現對應於cd_store的iterator。
可見,iterator模式在各種iterator中封裝了檢索元素的方法。
將容器和對容器中元素的操作完全隔開。
大大增加了程式碼的可重用性。
在網路上看帖子時發現不少模式的初學者對Iterator模式的理解僅僅停留在從類庫的容器類取得Iterator來遍歷容器中的內容的程度。
因此在這裡寫幾個例子,來加深大家對Iterator模式的理解。
對容器中元素的訪問涉及到3個方面。
1.容器的型別
2.檢索容器內元素的方法
3.對元素的操作
比如說我們有一個表示書店的book_store類。裡面儲存了各種各樣的book類的例項。
book類有name和type兩種屬性。表示書的名字和類別。
因此book_store類內部會用一個容器來儲存book的例項。比如list。
class book
{
public:
string name;
string type;
};
class book_store
{
private:
list<book> m_books;
};
我們現在有這樣一個簡單的應用,那就是輸出所有的書名到螢幕。
那麼我們來看一下在引入Iterator模式前有那幾種實現方法,各有什麼缺點。
1.給book_store類增加一個print_book_name的函式。來實現這個功能。
這樣做的缺點有兩個:
(1).將輸入輸出邏輯和業務物件繫結在一起,導致了今後系統難以變更。
(2).輸出邏輯和內部實現繫結。
比如現在要把輸出到螢幕改成輸出到log檔案的話,那麼就需要修改print_book_name了。
2.給book_store類增加一個get_list函式。然後寫一個print_book類來負責列印書名的列表。這是一個初學者常用的方式。表面上看來似乎兩個類各擔其責,一個表示業務物件一個負責列印。
如果需要列印到log檔案的話,只要新增加一個log_book類,book_store和print_book都不受影響。解決了上面的這個問題。
這樣做的缺點是:
(1).把book_store類的內部實現給暴露出來了,違反了封裝的原則。
如果現在把內部容器型別從list換成了vector的話,就要修改輸出邏輯了。也就是說,要同時改寫print_book類和log_book類。
3.增加一個list和vector類共同的基類/介面,比如I_container。然後給book_store類增加一個get_books函式,返回I_container。
這在一定程度上解決了上面的問題。但是並不徹底。應為還是暴露了內部的實現,只不過從list上升到了I_container。
· 如果現在系統發生了變化,book_store不再在本地儲存books了,而是需要透過網路取得的話,print_book和log_book就無法對應了。
· 另一個限制是,我需要一個新的機能,那就是列印所有type為”烹飪書”的機能的話,就需要一個print_cook_book類了,而這裡邊的格式化程式碼和輸出程式碼和print_book是相同的。重複程式碼是維護的噩夢。
接下來我們看一下Iterator模式如何解決以上的這些問題。
首先,我們引入一個I_iterator的Interface。
然後建立一個I_iterator的實現類all_book_iterator。這個類可以迭代book_store中的所有book。
接下來建立一個print_book類,從I_iterator中取得每一個book,然後列印到螢幕。
下面我們看一下如何對應上面的這些需求變更。
1.要求輸出到log檔案
追加一個log_book類,其他都類都不需要改變。
2.將內部容器從list變成vector。
修改iterator中的相關程式碼。Iterator的使用者不會受到影響。
3.從網路取得資料。
修改iterator中的相關程式碼。Iterator的使用者不會受到影響。
4.按照type檢索
在iterator中新增一個type的屬性,或者是構造一個新的type_search_iterator。
在iterator中把不符合檢索條件的book過濾掉。
5.按照某一特定順序輸出book名到螢幕,或是log檔案。
實現一個按該順序輸出的iterator。
6.以同樣的方式列印cd_store。
實現對應於cd_store的iterator。
可見,iterator模式在各種iterator中封裝了檢索元素的方法。
將容器和對容器中元素的操作完全隔開。
大大增加了程式碼的可重用性。
相關文章
- 模型事件幾種用法模型事件
- webwork iterator標籤的用法Web
- ESB的幾種模式模式
- Iterator模式模式
- java定時器的幾種用法Java定時器
- 建立物件的幾種模式物件模式
- [Vuex系列] - 細說state的幾種用法Vue
- python幾種裝飾器的用法Python
- Java for迴圈的幾種用法詳解Java
- c++中&符號的幾種用法C++符號
- Java隨機數的幾種有趣用法Java隨機
- 迭代器模式(Iterator)模式
- 個人使用Kotlin的幾種習慣用法Kotlin
- Android Intent的幾種用法全面總結AndroidIntent
- 常見的幾種設計模式設計模式
- Docker幾種網路模式Docker模式
- 關於AI、關於chatGPT的幾十種用法AIChatGPT
- 談談服務端快取的幾種用法服務端快取
- 關於INLIST ITERATOR的幾個測試
- spring注入bean的幾種策略模式SpringBean模式
- Thrift server端的幾種工作模式分析Server模式
- laravel模板中生成URL的幾種模式Laravel模式
- java幾種代理模式的實現方式Java模式
- Vim常見模式有幾種?模式
- python中星號變數的幾種特殊用法Python變數
- 【轉】C#中base關鍵字的幾種用法C#
- Shell 中 $ 關於指令碼引數的幾種用法指令碼
- 設計模式的征途—21.迭代器(Iterator)模式設計模式
- 談談設計模式 —— Iterator設計模式
- 實現單例模式的 9 種方法,你知道幾種?單例模式
- Iterator(迭代器)的用法及其背後機制的探究
- Go 語言中常見的幾種反模式Go模式
- 幾種常用設計模式的簡單示例設計模式
- 模式識別的幾種基本演算法模式演算法
- iOS元件化常用的幾種構建模式iOS元件化模式
- 關於Jsoup 抓取精準資料的幾種用法JS
- 單例模式有幾種寫法?單例模式
- workerman / 小談PHP中的幾種執行模式PHP模式