迭代器模式
从表明理解就是一个接一个。就和排队买东西一样,对于商家而言,需要照顾到每一个排队的人,保证每个人都能买到东西,如果限量请提前说明(即总数需要明确),并且在购买的时候,商家只需要知道“你付钱了”,就需要把东西给你,不需要了解你姓名、电话号码等等其他的个人信息,只需要保证你付钱了就像。而迭代器模式就是提供一种方法顺序访问一个聚合对象(一条队伍)中的所有元素,并且不用暴露对象的内部信息(个人信息)。
Iterator:迭代器抽象类,存储的是共同的方法
ConcreteIterator:具体的迭代器抽象类,一般需要存储列表数据和共同方法的具体实现
Aggregate:聚集抽象类,存储的是聚集对象类的共同数据和方法
ConcreteAggregate:具体聚集类,存储需要遍历的数据和数据相关参数的获取设置接口
场景:
- 访问一个聚集对象的每个元素,但是不需要暴露内部数据
- 一个聚合对象需要多种遍历方式
- 对不同的聚合对象可用使用同一套遍历方式
优点:
- 对于同一个聚集对象,可用实现多种遍历方式
- 简化了聚合类的遍历方式
- 可多线同时遍历一个聚集对象
- 易拓展新的遍历方式或者拓展新的需要遍历的聚合对象
缺点:
- 过犹不及,太多的聚合类和方式类,可能使得类过多
实操
在写代码的时候,如果不能一步到位的把全部需要用到的方法进行定义,可以采用引导式,比如先写迭代器抽象的方法,当你具体方法的时候,就知道需要在聚集了中添加获取元素、获取大小的方法,而在写main使用的时候,就会知道需要添加Add函数,给据聚集类添加数据
思维:
- 先规定遍历方式方法,写出IIierator,定出需要实现提供的遍历方式
- 完成CConcreteIterator,去实现需要实现的方法
- 完成IAggregate,在之前的引导下,可以定下来大体需要那些接口去支持迭代器的功能,然后有需要提供元素的设置接口,因此Add式需要添加的
- 完成具体类的编写,只是实现抽象类中定义的方法
// IteratorModel.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
#include <string>
#include <vector>
using namespace std;
#define interface struct
interface IIterator
{
public:
virtual string getFirst() = 0;
virtual string getNext() = 0;
virtual bool isEnd() = 0;
virtual bool isEmpty() = 0;
virtual string currentItem() = 0;
};
interface IAggregate
{
public:
virtual IIterator* createIterator() = 0;
virtual string getObject(int index) = 0;
virtual void addObject(string str) = 0;
virtual int getCount() = 0;
};
class CConcreteIterator :public IIterator
{
private:
IAggregate* m_aggregate;
int m_currentIndex = 0;
public:
CConcreteIterator(IAggregate* aggregate) { m_aggregate = aggregate; }
string getFirst() { return m_aggregate->getObject(0); }
string getNext()
{
if (m_currentIndex <= m_aggregate->getCount() - 1)
{
return m_aggregate->getObject(m_currentIndex++);
}
else if (m_currentIndex == m_aggregate->getCount())
{
return "到底了";
}
return "到底了";
}
bool isEnd()
{
return (m_currentIndex >= (m_aggregate->getCount()));
}
bool isEmpty()
{
return (m_aggregate->getCount() == 0);
}
string currentItem()
{
return m_aggregate->getObject(m_currentIndex);
}
};
class CConcreteAggregate :public IAggregate
{
private:
vector<string> m_data;
public:
IIterator* createIterator()
{
return new CConcreteIterator(this);
}
string getObject(int index)
{
if (index >= 0 && index < m_data.size())
return m_data[index];
return "";
}
void addObject(string str)
{
m_data.push_back(str);
}
int getCount() { return m_data.size(); }
};
int main()
{
IAggregate* aggre = new CConcreteAggregate();
aggre->addObject("data1");
aggre->addObject("data2");
aggre->addObject("data3");
aggre->addObject("data4");
aggre->addObject("data5");
IIterator* iteror = new CConcreteIterator(aggre);
while (!iteror->isEnd())
{
cout << iteror->currentItem() << endl;
iteror->getNext();
}
}