迭代器模式又叫迭代模式。迭代器模式提供了一种顺序访问聚合对象中各元素的方法,隐藏了对象的内部结构,为遍历不同聚合结构,提供了如“开始”、“下一个”、“是否遍历结束”、“当前遍历位置”等统一的操作接口。即该模式在遍历容器之前,新定义了一个外部类,容器把对内部对象的遍历访问委派外部类。
在使用该模式之前,我们应该明白迭代器模式是用来解决什么问题的,或者说,如果不使用该模式而使用其他方法会存在什么问题。遍历容器的方法有两个:
- 由容器自己实现遍历,即在容器内直接提供遍历方法。但该方法有个缺点就是容器类承担了过多的功能,一方面要负责容器内元素的增删改查,还需要提供一个遍历方法,很容易引起程序混乱甚至运行出错。
- 让调用者自己实现遍历。但这个很明显的缺点就是暴露数据细节给客户,这是很危险的操作。
优点: 1、它支持以不同的方式遍历一个聚合对象。 2、迭代器简化了聚合类。 3、在同一个聚合上可以有多个遍历。 4、在迭代器模式中,增加新的聚合类和迭代器类都很方便,无须修改原有代码。
缺点:由于迭代器模式将存储数据和遍历数据的职责分离,增加新的聚合类需要对应增加新的迭代器类,类的个数成对增加,这在一定程度上增加了系统的复杂性。
类图如下:
示例代码如下:
#include <iostream>
using namespace std;
typedef int Object;
#define SIZE 5
/* 抽象迭代器基类 */
class MyIterator
{
public:
virtual void First() = 0;
virtual void Next() = 0;
virtual bool IsDone() = 0;
virtual Object CurrentItem() = 0;
};
/* 抽象容器基类 */
class Aggregate
{
public:
virtual MyIterator *CreateIterator() = 0;
virtual Object getItem(int index) = 0;
virtual int getSize() = 0;
};
/* 具体迭代器子类 */
class ContreteIterator : public MyIterator
{
public:
/* 根据传入的容器类,初始化迭代器类 */
ContreteIterator(Aggregate * ag)
{
_ag = ag;
_current_index = 0;
}
virtual void First()
{
_current_index = 0; //让当前 游标 回到位置0
}
virtual void Next()
{
if (_current_index < _ag->getSize())
{
_current_index++;
}
}
virtual bool IsDone()
{
return (_current_index == _ag->getSize());
}
virtual Object CurrentItem()
{
return _ag->getItem(_current_index);
}
private:
int _current_index;
Aggregate * _ag;
};
/* 具体容器子类 */
class ConcreteAggregate : public Aggregate
{
public:
/* 给容器内元素初始化 */
ConcreteAggregate()
{
for (int i = 0; i < SIZE; i++)
{
object[i] = i + 100;
}
}
/* 创建该容器对象自己的迭代器对象 */
virtual MyIterator *CreateIterator()
{
return new ContreteIterator(this); //让迭代器 持有一个 集合的 引用
}
/* 获取当前索引对应的值 */
virtual Object getItem(int index)
{
return object[index];
}
/* 获取当前容器内元素个数 */
virtual int getSize()
{
return SIZE;
}
private:
Object object[SIZE];
};
void main()
{
/* 创建容器 */
Aggregate * ag = new ConcreteAggregate;
/* 创建该容器的迭代器 */
MyIterator *it = ag->CreateIterator();
/* 从当前容器索引遍历元素 */
for (; !(it->IsDone()); it->Next())
{
cout << it->CurrentItem() << " ";
}
cout << endl;
delete it;
delete ag;
system("pause");
return;
}
代码运行结果如下: