迭代器模式:提供一種方法順序訪問一個聚合對象中的各個元素,且不用暴露該對象的內部表示。【對象行爲型模式】
定義:
- 分聚合類(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