概念:提供一种方法顺序访问一个聚合对象中各个元素,而又不需暴露该对象的内部表示。
Iterator 模式典型的结构图为:
Iterator 模式中定义的对外接口可以视客户成员的便捷定义,但是基本的接口在图中的Iterator 中已经给出了(参考 STL 的 Iterator 就知道了)。
周五下午,我正在看技术网站,第六感官发觉有人在身后,扭头一看,我 C,老大站在背后,赶忙站起来,“王经理,你找我?” 我说。
“哦,在看技术呀。有个事情找你谈一下,你到我办公室来一下。” 老大说。到老大办公室,“是这样,刚刚我在看季报,我们每个项目的支出费用都很高,项目情况复杂,人员情况也不简单,我看着也有点糊涂,你看,这是我们现在还在开发或者维护的 103 个项目,你能不能先把这些项目信息重新打印一份给我,咱们好查查到底有什么问题。”
老大说。“这个好办,我马上去办”我爽快的答复道。 很快我设计了一个类图,并开始实施:
老大一看,非常 Happy,这么快就出结果了,大大的把我夸奖了一番,然后就去埋头去研究那堆枯燥的报表了,然后我回到座位上,又看了一遍程序(心里很乐,就又想看看自己的成果),想想了,应该还有另外一种实现方式,因为是遍历嘛,让我想到的就是迭代器模式,我先把类图画出来:
main(),客户
IProject,产品接口
CProject,产品类
IIterator,迭代器接口
IProjectIterator,产品迭代器接口
CProjectIterator,产品迭代器实现类
Convert,整型转字符型
说明:CProject实现产品类,能够返回一个迭代器的指针。这个迭代器将封装产品类里的一个数组。所以迭代器在运行Next函数时,可以遍历这个数组的所有元素。
简单来说,就是用代码实现vector<int>::iterator或vector<int>::const_iterator。
代码:
迭代器接口:IIterator类
IIterator.h
#ifndef __Iterator__IIterator__ #define __Iterator__IIterator__ #include <iostream> #include "IProject.h" class IProject; class IIterator { public: IIterator(void) { } virtual ~IIterator(void) { } virtual bool HasNext() = 0; virtual IProject * Next() = 0; }; #endif /* defined(__Iterator__IIterator__) */
IProjectIterator.h
#ifndef __Iterator__IProjectIterator__ #define __Iterator__IProjectIterator__ #include <iostream> #include "IIterator.h" class IProject; class IProjectIterator:public IIterator { public: IProjectIterator(void) { } virtual ~IProjectIterator(void) { } virtual bool HasNext() = 0; virtual IProject * Next() = 0; }; #endif /* defined(__Iterator__IProjectIterator__) */
CProjectIterator.h
#ifndef __Iterator__ProjectIterator__ #define __Iterator__ProjectIterator__ #include <iostream> #include "IProjectIterator.h" #include "IProject.h" #include <vector> using std::vector; class CProjectIterator:public IProjectIterator { public: //构造函数传入projectList CProjectIterator(vector<IProject *> pl); ~CProjectIterator(void); //判断是否还有元素,必须实现 bool HasNext(); //取得下一个值 IProject * Next(); private: vector<IProject *> m_projectList; //所有的项目都放在这里vector中 size_t m_currentItem; }; #endif /* defined(__Iterator__ProjectIterator__) */CProjectIterator.cpp
#include "ProjectIterator.h" CProjectIterator::CProjectIterator(vector<IProject *> pl) : m_projectList(pl) { m_currentItem = 0; } CProjectIterator::~CProjectIterator(void) { } bool CProjectIterator::HasNext() { bool b = true; if (m_currentItem >= m_projectList.size()) b = false; return b; } IProject * CProjectIterator::Next() { IProject *pp = m_projectList.at(m_currentItem ++); return pp; }
产品接口:IProject类
IProject.h
#ifndef __Iterator__IProject__ #define __Iterator__IProject__ #include <iostream> #include "IProjectIterator.h" class IProjectIterator; using std::string; class IProject { public: IProject(void) { } virtual ~IProject(void) { } //增加项目 virtual void Add(string name, int num, int cost) = 0; //从老板这里看到的就是项目信息 virtual string GetProjectInfo() = 0; //获得一个可以被遍历的对象 virtual IProjectIterator* GetIterator() = 0; virtual void Erase() = 0; }; #endif /* defined(__Iterator__IProject__) */
CProject.h
#ifndef __Iterator__Project__ #define __Iterator__Project__ #include <iostream> #include "IProject.h" #include "IProjectIterator.h" #include "ProjectIterator.h" #include <vector> using std::string; using std::vector; class CProject :public IProject { public: CProject(void); //定义一个构造函数,把所有老板需要看到的信息存储起来 CProject(string name, int num, int cost); ~CProject(void); //得到项目的信息 string GetProjectInfo(); //增加项目 void Add(string name, int num, int cost); //产生一个遍历对象 IProjectIterator * GetIterator(); //删除一个对象 void Erase(); private: string m_name; //项目名称 int m_num; //项目成员数量 int m_cost; //项目费用 vector<IProject*> m_projectList; //定义一个项目列表,说有的项目都放在这里 }; #endif /* defined(__Iterator__Project__) */CProject.cpp
#include "Project.h" #include "Convert.h" CProject::CProject( void ) { m_name = ""; m_num = 0; m_cost = 0; } CProject::CProject(string name, int num, int cost) :m_name(name), m_num(num), m_cost(cost) { } CProject::~CProject(void) { } string CProject::GetProjectInfo() { string info = ""; info.append("项目名称是:"); info.append(this->m_name); info.append("\t项目人数:"); info.append(CConvert::ToString(m_num)); info.append("\t项目费用:"); info.append(CConvert::ToString(m_cost)); return info; } void CProject::Add( string name, int num, int cost ) { this->m_projectList.push_back(new CProject(name, num, cost)); } IProjectIterator * CProject::GetIterator() { return new CProjectIterator(this->m_projectList); } void CProject::Erase() { vector<IProject*>::reverse_iterator projectDelIt = m_projectList.rbegin(); for (; projectDelIt != m_projectList.rend(); projectDelIt++) { delete (*projectDelIt); (*projectDelIt) = NULL; } m_projectList.clear(); }
Convert.h
#include <iostream> using std::string; #ifdef COMMONDECLARE_EXPORTS #define COMMONDECLARE_API __declspec(dllexport) #else #define COMMONDECLARE_API __declspec(dllimport) #endif class COMMONDECLARE_API CConvert { public: CConvert(void); ~CConvert(void); static string ToString(int i); };Convert.cpp
#include "Convert.h" #include <iostream> #include <sstream> using std::string; using std::stringstream; CConvert::CConvert(void) { } CConvert::~CConvert(void) { } string CConvert::ToString(int i) { stringstream ss; ss << i; string result = ss.str(); return result; }
main.cpp
#include <iostream> #include "IProject.h" #include "Project.h" #include "Convert.h" #include "ProjectIterator.h" #include <vector> using std::vector; using std::cout; using std::endl; void DoIt() { cout << "----------未使用迭代模式----------" << endl; vector<IProject*> projectList; projectList.push_back(new CProject("星球大战项目", 10, 100000)); projectList.push_back(new CProject("扭转时空项目", 100, 10000000)); projectList.push_back(new CProject("超人改造项目", 10000, 1000000000)); for (int i = 4; i < 6; i ++) { string name = ""; name.append("第"); name.append(CConvert::ToString(i)); name.append("个项目"); projectList.push_back(new CProject(name, i * 5, i * 1000000)); } vector<IProject*>::const_iterator projectIt = projectList.begin(); for (; projectIt != projectList.end(); projectIt++) cout << (*projectIt)->GetProjectInfo().c_str() << endl; vector<IProject*>::reverse_iterator projectDelIt = projectList.rbegin(); for (; projectDelIt != projectList.rend(); projectDelIt++) { delete (*projectDelIt); (*projectDelIt) = NULL; } projectList.clear(); } void DoNew() { cout << "----------使用迭代模式----------" << endl; IProject *pproject = new CProject(); pproject->Add("星球大战项目", 10, 100000); pproject->Add("扭转时空项目", 100, 10000000); pproject->Add("超人改造项目", 10000, 1000000000); for (int i = 4; i < 6; i ++) { string name = ""; name.append("第"); name.append(CConvert::ToString(i)); name.append("个项目"); pproject->Add(name, i * 5, i * 1000000); } IProjectIterator *pprojectIt = pproject->GetIterator(); while(pprojectIt->HasNext()) { IProject *p = dynamic_cast<IProject*>(pprojectIt->Next()); cout << p->GetProjectInfo().c_str() << endl; } delete pprojectIt; pprojectIt = NULL; pproject->Erase(); delete pproject; pproject = NULL; } int main(int argc, const char * argv[]) { //使用Iterator模式之前 DoIt(); //使用Iterator DoNew(); // insert code here... std::cout << "Hello, World!\n"; return 0; }
参考文献:《设计模式之禅》,《GoF_23种设计模式解析》
参考博客: http://www.cnblogs.com/wanggary/archive/2011/04/19/2021600.html