1. 意图
提供一种方法顺序访问一个聚合对象中各个元素, 而又不需暴露该对象的内部表示。
2. 动机
一个聚合对象, 如列表(list), 应该提供一种方法来让别人可以访问它的元素,而又不需暴露它的内部结构. 此外,针对不同的需要,可能要以不同的方式遍历这个列表。但是即使可以预见到所需的那些遍历操作,你可能也不希望列表的接口中充斥着各种不同遍历的操作。有时还可能需要在同一个表列上同时进行多个遍历。
提供一种方法顺序访问一个聚合对象中各个元素, 而又不需暴露该对象的内部表示。
2. 动机
一个聚合对象, 如列表(list), 应该提供一种方法来让别人可以访问它的元素,而又不需暴露它的内部结构. 此外,针对不同的需要,可能要以不同的方式遍历这个列表。但是即使可以预见到所需的那些遍历操作,你可能也不希望列表的接口中充斥着各种不同遍历的操作。有时还可能需要在同一个表列上同时进行多个遍历。
迭代器模式都可帮你解决所有这些问题。这一模式的关键思想是将对列表的访问和遍历从列表对象中分离出来并放入一个迭代器(i t e r a t o r)对象中。迭代器类定义了一个访问该列表元素的接口。迭代器对象负责跟踪当前的元素; 即, 它知道哪些元素已经遍历过了。
3.结构
Iterator:定义迭代器访问和遍历元素的接口;
ConcreteIterator:实现具体的迭代器;
Aggregate:定义的容器,创建相应迭代器对象的接口;
ConcreteAggregate:具体的容器实现创建相应迭代器的接口,该操作返回ConcreteIterator的一个适当的实例。
4.举例
#ifndef ITERATOR_H
#define ITERATOR_H
#include <string>
#include <vector>
using std::vector;
using std::string;
class Iterator{
public:
Iterator(){}
virtual ~Iterator(){}
virtual string First()=0;
virtual string Next()=0;
virtual string GetCur()=0;
virtual bool IsEnd()=0;
};
class Aggregate{
public:
virtual ~Aggregate(){}
virtual int Count()=0;
virtual void Push(const string&)=0;
virtual string Pop(const int)=0;
virtual Iterator* CreateIterator()=0;
};
class ConcreateIterator : public Iterator{
private:
Aggregate* pAggregate;
int iCurrent;
public:
ConcreateIterator(Aggregate* temp): pAggregate(temp),iCurrent(0){}
virtual string First(){
return pAggregate->Pop(0);
}
virtual string Next(){
iCurrent++;
if(iCurrent<pAggregate->Count())
return pAggregate->Pop(iCurrent);
else
return "";
}
virtual string GetCur(){
return pAggregate->Pop(iCurrent);
}
virtual bool IsEnd(){
if(iCurrent<pAggregate->Count())
return false;
else
return true;
}
};
class ConcreteAggregate : public Aggregate{
private:
vector<string> arr;
Iterator* pIterator;
public:
ConcreteAggregate(): arr(NULL),pIterator(NULL){}
~ConcreteAggregate(){
if(pIterator){
delete pIterator;
pIterator=NULL;
}
}
virtual Iterator* CreateIterator(){
if(pIterator==NULL){
pIterator=new ConcreateIterator(this);
}
return pIterator;
}
virtual int Count(){
return arr.size();
}
virtual void Push(const string& temp){
arr.push_back(temp);
}
virtual string Pop(const int temp){
if(temp<Count())
return arr[temp];
else
return NULL;
}
};
#endif
#include "iterator.h"
#include <iostream>
using std::cout;
using std::endl;
int main(){
Aggregate* pName=new ConcreteAggregate;
pName->Push("Tom");
pName->Push("James");
pName->Push("Kobe");
pName->Push("Jordan");
Iterator* pIterator=pName->CreateIterator();
for(;!pIterator->IsEnd();pIterator->Next()){
cout<<pIterator->GetCur()<<endl;
}
cout<<pIterator->First()<<endl;
return 0;
}