设计模式之迭代器模式(Iterator Pattern)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/w_x_myself/article/details/82179011

1、定义

用于顺序访问集合对象的元素,不需要知道集合对象的底层表示。

迭代器模式属于行为型模式。

2、介绍

优点: 1、它支持以不同的方式遍历一个聚合对象。 2、迭代器简化了聚合类。 3、在同一个聚合上可以有多个遍历。 4、在迭代器模式中,增加新的聚合类和迭代器类都很方便,无须修改原有代码。

缺点:由于迭代器模式将存储数据和遍历数据的职责分离,增加新的聚合类需要对应增加新的迭代器类,类的个数成对增加,这在一定程度上增加了系统的复杂性。

使用场景: 1、访问一个聚合对象的内容而无须暴露它的内部表示。 2、需要为聚合对象提供多种遍历方式。 3、为遍历不同的聚合结构提供一个统一的接口。

注意事项:迭代器模式就是分离了集合对象的遍历行为,抽象出一个迭代器类来负责,这样既可以做到不暴露集合的内部结构,又可让外部代码透明地访问集合内部的数据。

3、源码

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;
};

IIterator.h

#pragma once
#include<vector>
#include<iostream>
using namespace std;
class IProject;
class IIterator
{
public:
	IIterator(void)
	{
	}
	virtual ~IIterator(void)
	{
	}
	virtual bool HasNext() = 0;
	virtual IProject * Next() = 0;
};

IProjectIterator.h

#pragma once
#include "iiterator.h"
class IProject;
class IProjectIterator :
	public IIterator
{
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);
	}

	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()
{
	//使用Iterator模式之前
	DoIt();

	//使用Iterator
	DoNew();

	system("pause");

	return 0;
}

4、结果

参考文献:《菜鸟教程》   https://blog.csdn.net/phiall/article/details/52199659博客

猜你喜欢

转载自blog.csdn.net/w_x_myself/article/details/82179011