iT邦幫忙

2024 iThome 鐵人賽

DAY 15
0
Software Development

輕鬆學習設計模式Design Pattern系列 第 15

Day 15 迭代器模式 Iterator Pattern

  • 分享至 

  • xImage
  •  

你是否曾經面對過需要遍歷一個集合、而又不希望暴露它的內部結構的情況?這就像我們在看一本書時,並不需要知道書本是如何裝訂的,只需要翻頁就好。這時迭代器模式就派上用場了。迭代器模式提供了一種簡單且一致的方式來訪問集合中的元素,讓你不必為了遍歷資料而大費周章。

什麼是迭代器模式?

迭代器模式是一種行為設計模式,它允許你逐一訪問集合物件的元素,而不需要暴露其底層的表示方式。想像你有一個儲存很多物件的容器,但你並不想揭露這些物件如何被儲存的細節。透過迭代器模式,你可以透過一個統一的界面來訪問這些元素,無論是陣列、鏈結串列還是其他資料結構,都可以輕鬆遍歷。

迭代器模式在音樂播放清單中的應用

假設我們有一個音樂播放清單,這個清單內部可能是用陣列或鏈結串列來儲存歌曲,但作為使用者,你只想能夠播放下一首歌,不關心它的儲存結構。我們可以使用迭代器模式來實現這個功能。

首先我們需要定義一個迭代器介面,這個介面會告訴使用者是否有下一首歌,並且允許他們拿到下一首歌曲,

// 迭代器介面
class Iterator {
public:
    virtual bool hasNext() = 0;
    virtual std::string next() = 0;
    virtual ~Iterator() {}
};

接下來我們建立一個音樂清單類別,並且實作一個迭代器,這個迭代器會知道如何遍歷歌曲清單,

// 音樂清單迭代器
class PlaylistIterator : public Iterator {
private:
    std::vector<std::string> songs;
    int position;
public:
    PlaylistIterator(const std::vector<std::string>& songs)
     : songs(songs), position(0) {}

    bool hasNext() override {
        return position < songs.size();
    }

    std::string next() override {
        if (hasNext()) {
            return songs[position++];
        }
        return "";
    }
};

// 音樂清單類別
class Playlist {
private:
    std::vector<std::string> songs;
public:
    void addSong(const std::string& song) {
        songs.push_back(song);
    }

    Iterator* createIterator() {
        return new PlaylistIterator(songs);
    }
};

在客戶端使用時,使用者不需要知道清單如何儲存歌曲,他們只需要使用迭代器提供的 next() 方法來依序播放,

int main() {
    Playlist playlist;
    playlist.addSong("Song 1");
    playlist.addSong("Song 2");
    playlist.addSong("Song 3");

    Iterator* it = playlist.createIterator();
    while (it->hasNext()) {
        std::cout << "Playing: " << it->next() << std::endl;
    }
    delete it;

    return 0;
}

在這個例子中,我們定義了一個 Iterator 介面,並且在 PlaylistIterator 中實作了這個介面,用來遍歷歌曲清單。使用者只需要呼叫 hasNext()next() 方法來逐步訪問清單中的歌曲,完全不用擔心清單的內部實現。

迭代器模式的優缺點

迭代器模式的優點在於它提供了一種統一的方式來遍歷集合,不論集合的內部結構如何變化。就像你可以用同樣的方法翻閱紙質書或電子書一樣,迭代器讓不同類型的集合能夠提供相同的操作方式。這使得程式碼變得更加靈活,因為你不需要修改訪問邏輯來適應不同的集合類型。

迭代器模式也有一些缺點。由於每一種集合類型都需要自己的迭代器實現,這會增加一些額外的程式碼。並且在某些情況下,如果集合的大小或複雜度較大,迭代器的操作效能可能會受到影響。除此之外,記憶體管理也需要謹慎處理。

總結

迭代器模式在需要遍歷複雜集合結構時非常實用,它提供了一個簡單、統一的操作介面。透過將遍歷行為封裝在迭代器中,程式設計師能夠專注於如何使用集合,而不是關心其內部細節。正如我們看書時只需專注於閱讀,不必擔心書本的裝訂一樣,迭代器模式讓操作集合變得更加直觀。

更多C++語言相關的文章,歡迎追蹤我的部落格。
https://shengyu7697.github.io/cpp-iterator-pattern/


上一篇
Day 14 狀態模式 State Pattern
下一篇
Day 16 中介者模式 Mediator Pattern
系列文
輕鬆學習設計模式Design Pattern18
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言