1、定义
用于顺序访问集合对象的元素,不需要知道集合对象的底层表示。
迭代器模式属于行为型模式。
2、介绍
优点: 1、它支持以不同的方式遍历一个聚合对象。 2、迭代器简化了聚合类。 3、在同一个聚合上可以有多个遍历。 4、在迭代器模式中,增加新的聚合类和迭代器类都很方便,无须修改原有代码。
缺点:由于迭代器模式将存储数据和遍历数据的职责分离,增加新的聚合类需要对应增加新的迭代器类,类的个数成对增加,这在一定程度上增加了系统的复杂性。
使用场景: 1、访问一个聚合对象的内容而无须暴露它的内部表示。 2、需要为聚合对象提供多种遍历方式。 3、为遍历不同的聚合结构提供一个统一的接口。
注意事项:迭代器模式就是分离了集合对象的遍历行为,抽象出一个迭代器类来负责,这样既可以做到不暴露集合的内部结构,又可让外部代码透明地访问集合内部的数据。
3、源码
类关系图:
设计思路: 1、定义项目基类IProject,具体项目规划由子类实现。2、定义一个容器,类型为基类(IProject),将项目放入到容器中。3、定义迭代器基类IProjectIterator,接收项目基类反馈过来的数据。4、定义迭代器基类的子类,确定迭代器类的具体实现方法(处理容器中的项目方法)。注:放入进来基类指向哪里,反馈出去时,基类依旧指向哪里
3.1、头文件
IProject.h
#pragma once
#include "IProjectIterator.h"
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;
};
Project.h
#pragma once
#include "iproject.h"
#include "IProjectIterator.h"
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;
};
IProjectIterator.h
#pragma once
#include<vector>
#include<iostream>
class IProject;
class IProjectIterator
{
public:
IProjectIterator(void)
{
}
virtual ~IProjectIterator(void)
{
}
virtual bool HasNext() = 0;
virtual IProject * Next() = 0;
};
ProjectIterator.h
#pragma once
#include "iprojectiterator.h"
#include "IProject.h"
#include <vector>
using std::vector;
class CProjectIterator :
public IProjectIterator
{
public:
CProjectIterator(vector<IProject *> pl);
~CProjectIterator(void);
bool HasNext();
IProject * Next();
private:
vector<IProject *> m_projectList;
size_t m_currentItem;
};
3.2、实现
Project.cpp
#include "Project.h"
#include "ProjectIterator.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项目人数:");
char buf1[20] = { 0 }, buf2[20] = { 0 };
sprintf_s(buf1, "%d", m_num);
info.append(buf1);
info.append("\t项目费用:");
sprintf_s(buf2, "%d", m_cost);
info.append(buf2);
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();
}
ProjectIterator.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;
}
Iterator.cpp
#include "IProject.h"
#include "Project.h"
#include "ProjectIterator.h"
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("第");
char buf[10] = { 0 };
sprintf_s(buf, "%d", i);
name.append(buf);
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("第");
char buf[10] = { 0 };
sprintf_s(buf, "%d", i);
name.append(buf);
name.append("个项目");
pproject->Add(name, i * 5, i * 1000000);//调用子类CProject的Add的方法,将变量放入到m_projectList的容器中(类型IProject)
}
IProjectIterator *pprojectIt = pproject->GetIterator();//父类指针指向子类对象CProjectIterator,并且将CProject的m_projectList的值赋给CProjectIterator的m_projectList
while (pprojectIt->HasNext())
{
IProject *p = dynamic_cast<IProject*>(pprojectIt->Next());
cout << p->GetProjectInfo().c_str() << endl;//调用子类对象CProject的方法
}
//迭代器的删除,防止指针野指针
delete pprojectIt;
pprojectIt = NULL;
pproject->Erase();
delete pproject;
pproject = NULL;
}
int main()
{
//使用Iterator模式之前
DoIt();
//使用Iterator
DoNew();
system("pause");
return 0;
}
4、结果
参考文献:《菜鸟教程》 https://blog.csdn.net/phiall/article/details/52199659博客