定义:提供一种方法访问一个容器(container)对角中的各个元素,而又不需要暴露该对象的内部细节。
组成:
1.迭代器角色(Iterator):迭代器角色负责定义访问和遍历元素的接口。
2.具体迭代器角色(Concrete Iterator):具体失口角色要实现迭代器接口,并要记录遍历中的当前位置。
3.容器角色(Container):窗口角色负责提供创建具体迭代器角色的接口。
4.具体容器角色(Concrete Container):具体窗口角色实现创建具体迭代器角色的接口---这个具体迭代器角色于该窗口的结构相关。
四、 实现自己的迭代器
在实现自己的迭代器的时候,一般要操作的容器有支持的接口才可以。而且我们还要注
意以下问题:
在迭代器遍历的过程中,通过该迭代器进行容器元素的增减操作是否安全呢?
在容器中存在复合对象的情况,迭代器怎样才能支持深层遍历和多种遍历呢?
以上两个问题对于不同结构的容器角色,各不相同,值得考虑。
五、 适用情况
由上面的讲述,我们可以看出迭代器模式给容器的应用带来以下好处:
1) 支持以不同的方式遍历一个容器角色。根据实现方式的不同,效果上会有差别。
2) 简化了容器的接口。但是在java Collection 中为了提高可扩展性,容器还是提供了遍历
的接口。
3) 对同一个容器对象,可以同时进行多个遍历。因为遍历状态是保存在每一个迭代器对象
中的。
由此也能得出迭代器模式的适用范围:
1) 访问一个容器对象的内容而无需暴露它的内部表示。
2) 支持对容器对象的多种遍历。
3) 为遍历不同的容器结构提供一个统一的接口(多态迭代)。
例子:
// 容器的抽象基类
class Aggregate
{
public:
virtual ~Aggregate(){}
virtual Iterater* CreateIterater(Aggregate *pAggregate) = 0;
virtual int GetSize() = 0;
virtual DATA GetItem(int nIndex) = 0;
};
// 迭代器的抽象基类
class Iterater
{
public:
virtual ~Iterater(){}
virtual void First() = 0;
virtual void Next() = 0;
virtual bool IsDone() = 0;
virtual DATA CurrentItem() = 0;
private:
};
// 一个具体的容器类,这里是用数组表示
class ConcreateAggregate
: public Aggregate
{
public:
ConcreateAggregate(int nSize)
: m_nSize(nSize)
, m_pData(NULL)
{
m_pData = new DATA[m_nSize];
for (int i = 0; i < nSize; ++i)
{
m_pData[i] = i;
}
}
virtual ~ConcreateAggregate();
virtual Iterater* CreateIterater(Aggregate *pAggregate)
{
return new ConcreateIterater(this);
}
virtual int GetSize()
{
return m_nSize;
}
virtual DATA GetItem(int nIndex)
{
if (nIndex < m_nSize)
{
return m_pData[nIndex];
}
else
{
return -1;
}
}
private:
int m_nSize;
DATA *m_pData;
};
// 访问ConcreateAggregate容器类的迭代器类
class ConcreateIterater
: public Iterater
{
public:
ConcreateIterater(Aggregate* pAggregate)
: m_pConcreateAggregate(pAggregate)
, m_nIndex(0)
{
}
virtual ~ConcreateIterater(){}
virtual void First()
{
m_nIndex = 0;
}
virtual void Next()
{
if (m_nIndex < m_pConcreateAggregate->GetSize())
{
++m_nIndex;
}
}
virtual bool IsDone()
{
return m_nIndex == m_pConcreateAggregate->GetSize();
}
virtual DATA CurrentItem()
{
return m_pConcreateAggregate->GetItem(m_nIndex);
}
private:
Aggregate *m_pConcreateAggregate;
int m_nIndex;
};
int main()
{
Aggregate* pAggregate = new ConcreateAggregate(4);
Iterater* pIterater = new ConcreateIterater(pAggregate);
for (; false == pIterater->IsDone(); pIterater->Next())
{
std::cout << pIterater->CurrentItem() << std::endl;
}
return 0;
}