设计模式16:迭代模式(Iterator)
迭代模式:
它提供了一种方法没有对象的顺序访问聚合对象的暴漏底层的细节。
Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation.
事实上这个设计模式用的非常多,可是设计的非常少。由于stl中的迭代器就是这个模式的应用。预计这个设计模式的名字就是用从stl中的迭代器而来的。
UML图:
主要包含:
- Iterator:定义了一系列遍历訪问元素的接口
- ConcreteIterator:实现了Iterator定义的接口,并保存了一个详细的Aggregate中遍历的元素的位置。
- Aggregate:抽象的Aggregate。定义了一个返回Iterator对象的接口
- ConcreteAggregate:实现了返回Iterator的接口。
理解这个设计模式时能够和STL中的迭代器一起考虑,这样上面各个角色的作用就非常明了了。
这个设计模式用C++实现的关键是Operator[]的编写。我们相当于定义了一种简易的容器,准确的说是一种容器适配器。
C++代码:
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
class Iterator;
class ConcreteIterator;
class Aggregate
{
};
//眼下还没有发现抽象的Aggregate的用途是什么。由于详细的迭代器须要知道ConcreteAggregate
//的内部实现细节。而在stl中是通过为每种easy定义一个内部迭代器类来保证的
class ConcreteAggregate:public Aggregate
{
public:
ConcreteAggregate()
{
datas=vector<string>(100);
}
friend class ConcreteIterator;
//这而事实上另一点问题。当datas元素超过100时会有问题。此时须要对内存又一次分配
string& operator[](const int &index)
{
return datas[index];
}
private:
vector<string> datas;
};
//抽象的迭代器类,提供了以下这个借口,在子类中能够详细实现这些接口的含义,比方stl中的正向
//和反向迭代器就是对接口的不同实现
class Iterator
{
public:
virtual string &first()=0;
virtual string next()=0;
virtual bool isDone()=0;
virtual string ¤tItem()=0;
};
class ConcreteIterator:public Iterator
{
public:
ConcreteIterator(ConcreteAggregate * agg)
{
aggregate=agg;
cur=0;
}
string& first()
{
return aggregate->datas[0];
}
string next()
{
if(cur+1<aggregate->datas.size())
{
cur+=1;
return aggregate->datas[cur];
}else
{
return NULL;
}
}
bool isDone()
{
int len=aggregate->datas.size();
if(cur==len-1)
return true;
else
return false;
}
string& currentItem()
{
return aggregate->datas[cur];
}
private:
ConcreteAggregate * aggregate;
int cur;
};
int main()
{
std::cout<<"迭代器模式測试"<<std::endl;
ConcreteAggregate agg ;
agg[0]="John";
agg[1]="Mike";
agg[2]="Bill";
agg[3]="Joe";
agg[4]="Kelly";
ConcreteIterator* iter=new ConcreteIterator(&agg);
std::cout<<iter->first()<<std::endl;
iter->next();
std::cout<<iter->currentItem()<<std::endl;
return 0;
}
运行输出:
版权声明:本文博主原创文章。博客,未经同意不得转载。