迭代器模式(Iterator Pattern)的定义
(1)定义:提供一种方法顺序访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部表示。
①迭代器迭代的是具体的聚合对象(如数组和链表等),它围绕的是“访问”做文章。
②可用不同的遍历策略来遍历聚合,比如是否需要过滤
③为不同聚合结构提供统一的迭代接口,也就是说通过一个迭代接口可以访问不同的聚合结构,这叫做多态迭代。标准的迭代模式实现基本上都是支持多态迭代的。如用同一个迭代接口来实现对数组和链表的遍历。
(2)迭代器模式的结构和说明
①Iterator:迭代器接口。定义访问和遍历元素的接口。
②ConcreteInterator:具体的迭代器实现对象,会持有被迭代的具体的聚合对象的引用,并对聚合对象的遍历及跟踪遍历时的当前位置。
③Aggregate:聚合对象。提供创建相应迭代器对象的函数(如createIterator())。
④ConcreteAggregate:具体聚合对象。实现创建相应迭代器对象。
【编程实验】以统一的方式对数组和链表进行遍历(多态迭代)
//声明文件
//行为模式——迭代器模式
//场景:统一数组类和链表类的操作及遍历方法
//说明:1、本实例没有采用内部类来实现具体的迭代器,目的是
// 为了演示与课本相同的结构图
// 2、调用next方法,除了可以获得相应元素,而且游标下移一个。
#include <iostream>
#include <string>
using namespace std;
//前向声明
class CAbsIt;
//***************************辅助类***************************
//容器存储的对象
class CObj{
public:
int iOid;
public:
CObj(int oid = 0);
~CObj();
void Disp();
};
//链表节点
typedef struct SNode{
SNode* pNext;
CObj* pObj;
SNode(CObj* obj, SNode* next);
~SNode();
}SNODE, *PSNODE;
//*******************************聚合类(Aggregate)接口************************
//抽象聚合类
class CAbsSet{
public:
virtual ~CAbsSet();
virtual int AddObj(CObj* obj) = 0;
virtual int Count() = 0;
virtual CAbsIt* CreateIterator() = 0;
virtual CObj* GetObj(int idx) = 0;
};
//***********************************迭代器接口*******************************
//抽象迭代器
class CAbsIt{
public:
virtual ~CAbsIt(){}
virtual CObj* Next() = 0;
virtual bool IsEnd() = 0;
};
//****************************************具体迭代器*******************************
//数组类的迭代器(因专为数组提供迭代,可以直接嵌入数组类作为其内部类使用,
//但这里为了与课本一致,先暂时分开)
class CArrayIt : public CAbsIt{
private:
CAbsSet* pSet;
int iCurrIdx;
public:
CArrayIt(CAbsSet* set);
CObj* Next();
bool IsEnd();
};
//链表类迭代器
class CListIt : public CAbsIt{
private:
CAbsSet* pSet;
int iCurrIdx;
public:
CListIt(CAbsSet* set);
CObj* Next();
bool IsEnd();
};
//************************************具体聚合类****************************************
//数组类
class CArray : public CAbsSet{
private:
CObj** pObjArr;//对象数组;
int iCount;
int iSize;
CAbsIt* pIt;
public:
CArray();
~CArray();
int Count();
int AddObj(CObj* obj);
CObj* GetObj(int idx);
CAbsIt* CreateIterator();
};
//链表类
class CList : public CAbsSet{
private:
PSNODE pTop;
int iCount;
CAbsIt* pIt;
public:
CList();
~CList();
int Count();
int AddObj(CObj* obj);
CAbsIt* CreateIterator();
CObj* GetObj(int idx);
};
//实现文件
//***************************辅助类***************************
//容器存储的对象
CObj::CObj(int oid){iOid = oid;}
CObj::~CObj(){ cout << "~CObj : " << iOid << endl;}
void CObj::Disp(){cout << "ObjectId : " << iOid << endl;}
//链表节点
SNode::SNode(CObj* obj, SNode* next){pObj = obj; pNext = next;}
SNode::~SNode(){delete pObj;}
//*******************************聚合类(Aggregate)接口************************
//抽象聚合类
CAbsSet::~CAbsSet(){}
//***********************************迭代器接口*******************************
//抽象迭代器
//****************************************具体迭代器*******************************
//数组类的迭代器(因专为数组提供迭代,可以直接嵌入数组类作为其内部类使用,
//但这里为了与课本一致,先暂时分开)
CArrayIt::CArrayIt(CAbsSet* set){pSet = set; iCurrIdx = 0;}
CObj* CArrayIt::Next(){ return pSet->GetObj(iCurrIdx++);}
bool CArrayIt::IsEnd(){ return !(iCurrIdx < pSet->Count());}
//链表类迭代器
CListIt::CListIt(CAbsSet* set){pSet = set;iCurrIdx = 0;}
CObj* CListIt::Next(){ return pSet->GetObj(iCurrIdx++);}
bool CListIt::IsEnd(){ return !(iCurrIdx < pSet->Count());}
//************************************具体聚合类****************************************
//数组类
CArray::CArray(){iSize = 10; iCount = 0; pObjArr = new CObj*[iSize]; pIt = NULL;}
CArray::~CArray(){
delete[] pObjArr;
if(pIt != NULL) delete pIt;
}
int CArray::Count(){ return iCount;}
int CArray::AddObj(CObj* obj){
if(iCount == iSize){
cout << "Error : Array OverFlow !" << endl; return iCount;
}
pObjArr[iCount] = obj;
return iCount++;
}
CObj* CArray::GetObj(int idx){
if(idx < 0 || idx >= iCount){
cout << "Error : Array UnderFlow !" << endl; return NULL;
}
return pObjArr[idx];
}
CAbsIt* CArray::CreateIterator(){
if(pIt == NULL) pIt = new CArrayIt(this);
return pIt;
}
//链表类
CList::CList(){ pTop = NULL; iCount = 0; pIt = NULL;}
CList::~CList(){
PSNODE sp = pTop, fp = pTop;
while(sp != NULL){//清空链表
fp = sp; sp = sp->pNext; delete fp;
}
if(pIt != NULL) delete pIt;
}
int CList::Count(){return iCount;}
int CList::AddObj(CObj* obj){
int iIdx = iCount;
if(obj == NULL) return iIdx;
PSNODE pNode = new SNODE(obj, NULL);
pNode->pNext = pTop; pTop = pNode; iCount++;
return iIdx;
}
CAbsIt* CList::CreateIterator(){
if(pIt == NULL) pIt = new CListIt(this);
return pIt;
}
CObj* CList::GetObj(int idx){
int iCurr = 0;
CObj* pObj = NULL;
PSNODE pNode = pTop;
while(pNode != NULL && iCurr <= idx){
if(iCurr == idx) pObj = pNode->pObj;
pNode = pNode->pNext; iCurr++;
}
return pObj;
}
//测试客户端
void main()
{
CAbsSet* pArray = new CArray();
CAbsSet* pList = new CList();
//面向接口编程,由于数组类和链表类继承自同一接口
//所以他们具有一的操作(如增加元素)
for(int i = 0; i < 15; i++){
CObj* pObj = new CObj(i+1);
pArray->AddObj(pObj);
pList->AddObj(pObj);
}
//由于Collection提供迭代器的接口,
//所以可以该接口对Collection及子类对象进行遍历
cout << "*************************************************" << endl;
CAbsIt* pIt = NULL;
pIt = pArray->CreateIterator();
while(!pIt->IsEnd()){
CObj* obj = pIt->Next(); obj->Disp();
}
cout << "*************************************************" << endl;
pIt = pList->CreateIterator();
while(!pIt->IsEnd()){
CObj* obj = pIt->Next(); obj->Disp();
}
cout << "*************************************************" << endl;
delete pList;
delete pArray;
}