文章目录
前言
Iterator 模式十分常见。当我们开发cpp文件时,经常会使用STL里面的容器,如vector、map、set等,对容器进行遍历的时候就用到了里面提供的Iterator来遍历数据结构。
Iterator模式也正是用来解决对一个聚合对象的遍历问题。其将对聚合的遍历封装到一个类中进行,这样就避免了暴露这个聚合对象的内部表示的可能。
一、迭代器模式(Iterator 模式)
Iterator模式中定义的对外接口可以视客户成员的便捷定义,但是基本的接口在图中的Iterator中已经给出了(参考 STL 的 Iterator 就知道了)。UML图如下:
二、具体源码
1.Aggregate.h
代码如下(示例):
#ifndef _AGGREGATE_H_
#define _AGGREGATE_H_
#include <iostream>
#include <vector>
typedef int Object;
class Iterator;
class Interator;
class Aggregate
{
public:
virtual ~Aggregate();
virtual Iterator* CreateIterator() = 0;
virtual Object GetItem(int idx) = 0;
virtual int GetSize() = 0;
protected:
Aggregate();
private:
};
class ConcreteAggregate :public Aggregate
{
public:
ConcreteAggregate(int size);
~ConcreteAggregate();
Iterator* CreateIterator();
Object GetItem(int idx);
int GetSize();
protected:
private:
std::vector<Object> _objs;
};
#endif //_AGGREGATE_H_
2.Aggregate.cpp
代码如下(示例):
#include "Aggregate.h"
#include "Iterator.h"
Aggregate::Aggregate()
{
}
Aggregate::~Aggregate()
{
}
ConcreteAggregate::ConcreteAggregate(int size)
{
this->_objs.resize(size, 0);
for (int i = 0; i < size; i++)
{
this->_objs[i] =i * i;
}
}
ConcreteAggregate::~ConcreteAggregate()
{
}
Iterator* ConcreteAggregate::CreateIterator()
{
return new ConcreteIterator(this);
}
Object ConcreteAggregate::GetItem(int idx)
{
if (idx < this->GetSize())
return _objs[idx];
else
return -1;
}
int ConcreteAggregate::GetSize()
{
return this->_objs.size();
}
3.Iterator.h
#pragma once
#ifndef _ITERATOR_H_
#define _ITERATOR_H_
class Aggregate;
typedef int Object;
class Iterator
{
public:
virtual ~Iterator();
virtual void First() = 0;
virtual void Next() = 0;
virtual bool IsDone() = 0;
virtual Object CurrentItem() = 0;
protected:
Iterator();
private:
};
class ConcreteIterator :public Iterator
{
public:
ConcreteIterator(Aggregate* ag, int idx = 0);
~ConcreteIterator();
void First();
void Next();
bool IsDone();
Object CurrentItem();
protected:
private:
Aggregate* _ag;
int _idx;
};
#endif //_ITERATOR_H_
4.Iterator.cpp
#include "Iterator.h"
#include "Aggregate.h"
Iterator::Iterator()
{
}
Iterator::~Iterator()
{
}
ConcreteIterator::ConcreteIterator(Aggregate* ag, int idx)
{
this->_ag = ag;
this->_idx = idx;
}
ConcreteIterator::~ConcreteIterator()
{
}
Object ConcreteIterator::CurrentItem()
{
return _ag->GetItem(_idx);
}
void ConcreteIterator::First()
{
_idx = 0;
}
void ConcreteIterator::Next()
{
if (_idx < _ag->GetSize())
_idx++;
}
bool ConcreteIterator::IsDone()
{
return (_idx == _ag->GetSize());
}
5.main.cpp
#include "Iterator.h"
#include "Aggregate.h"
int main(int argc, char* argv[])
{
const int size = 10;
Aggregate* ag = new ConcreteAggregate(size);
//默认从头开始遍历
Iterator* it1 = new ConcreteIterator(ag);
for (; !(it1->IsDone()); it1->Next())
{
std::cout << it1->CurrentItem() << std::endl;
}
std::cout << std::endl;
std::cout << "No start from first!!!" << std::endl;
Iterator* it2 = new ConcreteIterator(ag,5);
for (; !(it2->IsDone()); it2->Next())
{
std::cout << it2->CurrentItem() << std::endl;
}
return 0;
}
三、运行结果
Iterator 模式的运行结果如下:
总结
Iterator 模式中迭代器简化了聚合类,支持以不同的方式遍历一个聚合对象。 而且增加新的聚合类和迭代器类都很方便,无须修改原有代码。但是由于存储数据和遍历数据的职责分离,增加新的聚合类需要对应增加新的迭代器类,增加了系统的复杂度。
本文参考《设计模式精解-GoF 23 种设计模式解析附 C++实现源码》,对内容进行整理,方便大家学习。如想学习详细内容,请参考此书。