【設計模式】迭代器模式 C++ 行爲型模式

迭代器模式:提供一種方法順序訪問一個聚合對象各個元素不用暴露該對象的內部表示。【對象行爲型模式】

定義: 

  • 分聚合類(Aggreate Classes)和迭代類(Iterator)
  • 又名遊標(Cursor)模式
  • 訪問一個聚合對象中元素但是又不用暴露它的內部結構

適用環境:

  • 訪問一個聚合對象的內容而無需暴露它的內部表示
  • 需要爲一個聚合對象提供多種遍歷方式
  • 爲遍歷不同的聚合機構提供一個統一的接口,在該接口的實現類中爲不同的聚合結構提供不同的遍歷方式,而客戶端可以一致性的操作該接口

模式優點:

  • 支持以不同的方式遍歷一個聚合對象,在同一個聚合對象上可以定義多種遍歷方式
  • 簡化了聚合類
  • 由於引入了抽象層,增加新的聚合類和迭代類都很方便,無需修改原有的代碼,符合開閉原則

模式缺點:

  • 在增加新的聚合類時需要對應地增加新的迭代類,類的個數成對增加,這在一定程度上增加了系統的複雜性
  • 抽象迭代器的設計難度較大,需要充分考慮到系統將來的拓展。在定義迭代器時,創建一個考慮全面的抽象迭代器並不是一件容易的事情

類圖:

代碼:

#include <iostream>
#include <string>
#include <vector>

using namespace std;

class Iterator{
public:
    virtual string First() = 0;
    virtual string Next() = 0;
    virtual bool HasNext() = 0;
    virtual string CurrentItem() = 0;
};

class Aggregate{
public:
    virtual Iterator* CreteIterator() = 0;
    virtual void Push(const string &strValue) = 0;
    virtual string Pop(const int nIndex) = 0;
    virtual int Count() = 0;
};

class ConcreteIterator:public Iterator{
public:
    int m_Current;
    Aggregate *aggregate;
public:
    ConcreteIterator(Aggregate *p_aggregate):m_Current(0),Iterator(){
        aggregate = p_aggregate;
    }
    string First();
    string Next();
    bool HasNext();
    string CurrentItem();
};
string ConcreteIterator::First() {
    return aggregate->Pop(0);
}
string ConcreteIterator::Next() {
    if (HasNext()){
        string strRex;
        strRex = aggregate->Pop(++m_Current);
        return strRex;
    }else return "not have next";
}
bool ConcreteIterator::HasNext() {
    return (m_Current>=aggregate->Count()? false:true);
}
string ConcreteIterator::CurrentItem() {
    string strRex;
    strRex = aggregate->Pop(m_Current);
    return strRex;
}

class ConcreteAggregate:public Aggregate{
private:
    Iterator* m_Iterator;
    vector<string> m_vecItems;
public:
    ConcreteAggregate():m_Iterator(){
        m_vecItems.clear();
    }
    Iterator* CreteIterator();
    void Push(const string &strValue);
    string Pop(const int nIndex);
    int Count();
};
Iterator* ConcreteAggregate::CreteIterator() {
    if (m_Iterator == NULL){
        return new ConcreteIterator(this);
    }
    return m_Iterator;
}
void ConcreteAggregate::Push(const string &strValue) {
    m_vecItems.push_back(strValue);
}
string ConcreteAggregate::Pop(const int nIndex) {
    string strRex = "Index Error";
    if (nIndex < Count()){
        strRex = m_vecItems[nIndex];
    }
    return strRex;
}
int ConcreteAggregate::Count() {
    return m_vecItems.size();
}

int main(){
    ConcreteAggregate* pName = NULL;
    pName = new ConcreteAggregate();
    if (pName != NULL){
        pName->Push("Hello");
        pName->Push("World");
        pName->Push("This");
        pName->Push("is");
        pName->Push("C++");
    }
    Iterator* iterator = pName->CreteIterator();
    if (iterator != NULL){
        string StrItem = iterator->First();
        while (iterator->HasNext()){
            cout << "Item:\t";
            cout << iterator->CurrentItem() << "\tis OK" << endl;
            iterator->Next();
        }
    }
    return 0;
}

 運行結果:

Item:   Hello   is OK
Item:   World   is OK
Item:   This    is OK
Item:   is      is OK
Item:   C++     is OK

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章