一、简介
1. 定义
提供一种方法顺序访问一个聚合对象中各个元素,而又不需要暴露该对象的内部表示。
2. 应用场景
1)访问一个聚合对象的内容而无需暴露它的内部表示;
2)提供对聚合对象的多种遍历;
3)为遍历不同的聚合结构提供一个统一的接口,即支持多态迭代。
3. 优点
1)简化了类的聚合接口;
2)封装了对象的内部数据,降低耦合;
3)应用广泛,现在很多的库都提供了迭代功能,不需要程序员再重复造*。
4. 缺点
1)由于实现代码较为复杂,不太适应于简单的数据结构对象。
二、类图
Iterator:定义迭代器访问和遍历元素的接口;
ConcreteIterator:实现具体的迭代器;
Aggregate:定义的容器,创建相应迭代器对象的接口;
ConcreteAggregate:具体的容器实现创建相应迭代器的接口,该操作返回ConcreteIterator的一个适当的实例。
三、代码示例
本文以遍历书柜上的图书为例,简单实现迭代器模式:
#ifndef ITERATOR_H #define ITERATOR_H #include <QString> #include <QVector> #include <QDebug> using namespace std; class Iterator { public: Iterator() {}; virtual ~Iterator() {}; virtual QString First() = 0; virtual QString Next() = 0; virtual QString GetCur() = 0; virtual bool IsEnd() = 0; }; class Aggregate { public: Aggregate() {}; virtual ~Aggregate() {}; virtual int Count() = 0; virtual void Push(const QString& strValue) = 0; virtual QString Pop(int nIndex) = 0; virtual Iterator* CreateIterator() = 0; }; class BookIterator : public Iterator { public: BookIterator(Aggregate* pAggregate) :m_nCurrent(0) , Iterator() { m_Aggregate = pAggregate; } QString First() { return m_Aggregate->Pop(0); } QString Next() { QString strRet; m_nCurrent++; if (m_nCurrent < m_Aggregate->Count()) { strRet = m_Aggregate->Pop(m_nCurrent); } return strRet; } QString GetCur() { return m_Aggregate->Pop(m_nCurrent); } bool IsEnd() { return ((m_nCurrent >= m_Aggregate->Count()) ? true : false); } private: Aggregate* m_Aggregate; int m_nCurrent; }; class Bookcase : public Aggregate { public: Bookcase() :m_pIterator(nullptr) { m_bookVec.clear(); } ~Bookcase() { if (nullptr != m_pIterator) { delete m_pIterator; m_pIterator = nullptr; } } Iterator* CreateIterator() { if (nullptr == m_pIterator) { m_pIterator = new BookIterator(this); } return m_pIterator; } int Count() { return m_bookVec.count(); } void Push(const QString& strValue) { m_bookVec.push_back(strValue); } QString Pop(int nIndex) { QString bookStr; if (nIndex < Count()) { bookStr = m_bookVec[nIndex]; } return bookStr; } private: QVector<QString> m_bookVec; Iterator *m_pIterator; }; #if 1 #define FREE_OBJ(obj) if (nullptr != (obj)){delete (obj); (obj) = nullptr;} void main() { Bookcase* bookcase = new Bookcase(); bookcase->Push("SanGuoYanYi"); bookcase->Push("ShuiHuZhuan"); bookcase->Push("XiYouJi"); Iterator* iter = bookcase->CreateIterator(); if (nullptr != iter) { while (!iter->IsEnd()) { qDebug() << iter->GetCur(); iter->Next(); } } FREE_OBJ(bookcase); } #endif // 1 #endif // !ITERATOR_H