一、問題背景
????????Iterator 模式是設計模式中最為常見和實用的模式之一。它的核心思想是將對聚合對象的遍歷操作封裝到一個獨立的類中,從而避免暴露聚合對象的內部表示。通過 Iterator 模式,我們可以實現對聚合對象的統一遍歷接口,而不需要關心聚合對象的具體實現細節。
????????在實際開發中,Iterator 模式的應用非常廣泛。例如,在實現 Composite 模式、Flyweight 模式、Observer 模式時,我們經常會使用 STL 提供的 Iterator 來遍歷 `Vector` 或 `List` 等數據結構。Iterator 模式不僅簡化了遍歷操作,還提高了代碼的可維護性和可擴展性。
二、模式選擇
????????Iterator 模式的典型結構圖如下:
在 Iterator 模式中,主要包含以下幾個角色:
(1)Aggregate(聚合):定義創建 Iterator 對象的接口。
(2)ConcreteAggregate(具體聚合):實現 Aggregate 接口,返回一個具體的 Iterator 實例。
(3)Iterator(迭代器):定義遍歷聚合對象的接口。
(4)ConcreteIterator(具體迭代器):實現 Iterator 接口,負責遍歷具體的聚合對象。
????????通過這種設計,Iterator 模式將聚合對象的遍歷邏輯與其內部實現分離,使得聚合對象可以獨立于遍歷邏輯進行修改。
三、代碼實現
????????下面我們將通過一個完整的 C++ 代碼示例來展示如何實現 Iterator 模式。為了方便初學者的學習和參考,代碼將包含詳細的注釋。
代碼片段 1:Aggregate.h
// Aggregate.h
#ifndef _AGGREGATE_H_
#define _AGGREGATE_H_class Iterator;
typedef int Object; // 定義聚合對象中存儲的數據類型// Aggregate 類:定義創建 Iterator 對象的接口
class Aggregate {
public:virtual ~Aggregate();virtual Iterator* CreateIterator() = 0; // 創建迭代器virtual Object GetItem(int idx) = 0; // 獲取指定位置的元素virtual int GetSize() = 0; // 獲取聚合對象的大小
protected:Aggregate();
private:
};// ConcreteAggregate 類:具體聚合類,實現 Aggregate 接口
class ConcreteAggregate : public Aggregate {
public:enum { SIZE = 3 }; // 定義聚合對象的大小ConcreteAggregate();~ConcreteAggregate();Iterator* CreateIterator(); // 創建迭代器Object GetItem(int idx); // 獲取指定位置的元素int GetSize(); // 獲取聚合對象的大小
protected:
private:Object _objs[SIZE]; // 聚合對象中存儲的數據
};#endif //~_AGGREGATE_H_
代碼片段 2:Aggregate.cpp
// Aggregate.cpp
#include "Aggregate.h"
#include "Iterator.h"
#include <iostream>
using namespace std;// Aggregate 類的實現
Aggregate::Aggregate() {// 構造函數
}Aggregate::~Aggregate() {// 析構函數
}// ConcreteAggregate 類的實現
ConcreteAggregate::ConcreteAggregate() {// 初始化聚合對象中的數據for (int i = 0; i < SIZE; i++) {_objs[i] = i;}
}ConcreteAggregate::~ConcreteAggregate() {// 析構函數
}Iterator* ConcreteAggregate::CreateIterator() {// 創建具體的迭代器對象return new ConcreteIterator(this);
}Object ConcreteAggregate::GetItem(int idx) {// 獲取指定位置的元素if (idx < this->GetSize()) {return _objs[idx];} else {return -1; // 如果索引越界,返回 -1}
}int ConcreteAggregate::GetSize() {// 獲取聚合對象的大小return SIZE;
}
代碼片段 3:Iterator.h
// Iterator.h
#ifndef _ITERATOR_H_
#define _ITERATOR_H_class Aggregate;
typedef int Object; // 定義聚合對象中存儲的數據類型// Iterator 類:定義遍歷聚合對象的接口
class Iterator {
public:virtual ~Iterator();virtual void First() = 0; // 將迭代器指向第一個元素virtual void Next() = 0; // 將迭代器指向下一個元素virtual bool IsDone() = 0; // 判斷是否遍歷結束virtual Object CurrentItem() = 0; // 獲取當前元素
protected:Iterator();
private:
};// ConcreteIterator 類:具體迭代器類,實現 Iterator 接口
class ConcreteIterator : public Iterator {
public:ConcreteIterator(Aggregate* ag, int idx = 0); // 構造函數~ConcreteIterator();void First(); // 將迭代器指向第一個元素void Next(); // 將迭代器指向下一個元素bool IsDone(); // 判斷是否遍歷結束Object CurrentItem(); // 獲取當前元素
protected:
private:Aggregate* _ag; // 聚合對象int _idx; // 當前索引
};#endif //~_ITERATOR_H_
代碼片段 4:Iterator.cpp
// Iterator.cpp
#include "Iterator.h"
#include "Aggregate.h"
#include <iostream>
using namespace std;// Iterator 類的實現
Iterator::Iterator() {// 構造函數
}Iterator::~Iterator() {// 析構函數
}// ConcreteIterator 類的實現
ConcreteIterator::ConcreteIterator(Aggregate* ag, int idx) {this->_ag = ag; // 初始化聚合對象this->_idx = idx; // 初始化當前索引
}ConcreteIterator::~ConcreteIterator() {// 析構函數
}Object ConcreteIterator::CurrentItem() {// 獲取當前元素return _ag->GetItem(_idx);
}void ConcreteIterator::First() {// 將迭代器指向第一個元素_idx = 0;
}void ConcreteIterator::Next() {// 將迭代器指向下一個元素if (_idx < _ag->GetSize()) {_idx++;}
}bool ConcreteIterator::IsDone() {// 判斷是否遍歷結束return (_idx == _ag->GetSize());
}
代碼片段 5:main.cpp
// main.cpp
#include "Iterator.h"
#include "Aggregate.h"
#include <iostream>
using namespace std;int main(int argc, char* argv[]) {// 創建聚合對象Aggregate* ag = new ConcreteAggregate();// 創建迭代器對象Iterator* it = ag->CreateIterator();// 遍歷聚合對象for (; !(it->IsDone()); it->Next()) {cout << it->CurrentItem() << endl;}// 釋放內存delete it;delete ag;return 0;
}
代碼說明
(1)Aggregate 類:定義了創建 Iterator 對象的接口,并提供了獲取聚合對象大小和元素的方法。
(2)ConcreteAggregate 類:實現了 Aggregate 接口,內部維護了一個固定大小的數組。
(3)Iterator 類:定義了遍歷聚合對象的接口,包括移動到第一個元素、移動到下一個元素、判斷是否遍歷結束以及獲取當前元素的方法。
(4)ConcreteIterator 類:實現了 Iterator 接口,負責遍歷 ConcreteAggregate 對象。
?
四、總結討論
????????Iterator 模式的應用非常廣泛,尤其是在需要對聚合對象進行遍歷時。通過將遍歷邏輯封裝到獨立的 Iterator 類中,我們可以實現以下優點:
(1)簡化遍歷操作:客戶端代碼只需要調用 Iterator 的接口即可完成遍歷,無需關心聚合對象的內部實現。
(2)提高代碼復用性:可以為不同的聚合對象提供統一的遍歷接口。
(3)增強靈活性:可以在不修改聚合對象的情況下,擴展或修改遍歷邏輯。
????????在實際開發中,STL 提供的 Iterator 就是一個典型的應用。例如,我們可以使用 `std::vector<int>::iterator` 來遍歷 `std::vector<int>`,而無需關心 `std::vector` 的內部實現。
????????Iterator 模式通過將對聚合對象的遍歷操作封裝到獨立的類中,實現了遍歷邏輯與聚合對象的解耦。這種設計模式不僅簡化了代碼結構,還提高了代碼的可維護性和可擴展性。在實際開發中,Iterator 模式是處理聚合對象遍歷問題的首選方案。
?