迭代器模式是属于对象行为性的模式。首先是定义:
提供一种方法顺序访问一个聚合对象中各个元素,而又不暴露对象的表示方法。
迭代器的结构图:
适用性
1 访问一个聚合对象的内容而无需暴露它的内部表示
2 支持聚合对象的多种遍历
3 为遍历不同的聚合结构提供一个统一的接口(支持多态迭代)
协作
ConcreteIterator跟踪聚合中的当前对象,并能够计算出待遍历的后继对象
优点
1 支持以不同的方式遍历一个聚合
2 迭代器简化了聚合的接口
3 在同一个聚合上可以有多个遍历
实现
1 谁控制迭代
1 外部迭代:由客户控制迭代
2 内部迭代:有迭代器控制迭代
外部迭代灵活,特别是像C++这种静态语言(没有提供匿名函数)
内部迭代方便使用
2 谁定义迭代算法
由聚合本事也可提供迭代算法,这种迭代器成为游标
由迭代器提供遍历算法,方便提供在同一个聚合使用不同的遍历算法,但是有时遍历算法需要聚合的私有变量,如果这样就会破坏聚合的封装性
3 迭代器健壮程度如何
健壮的迭代器保证在保证插入和删除操作的时候不会干扰遍历和不需要拷贝该聚合
4 附加的迭代器操作
5 在C++使用多态的迭代器
6 迭代器可有特权访问
7 用于复合对象的迭代器
8 空迭代器
它的IsDone总是返回true
例子:
// IteratorModel.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "ConcreteAggregate.h"
#include "ConcreteIterator.h"
#include <iostream>
int _tmain(int argc, _TCHAR* argv[])
{
ConcreteAggregate* grreate = new ConcreteAggregate;
grreate->push("大鸟");
grreate->push("小菜");
grreate->push("行李");
grreate->push("老外");
grreate->push("内部员工");
grreate->push("小偷");
Iterator* it = new ConcreteIterator(grreate);
string first = it->First();
while ( it->isDone() )
{
cout << " " << it->currentItem() << "请买车票" << endl;
it->Next();
}
return 0;
}
/************************************************************************
@fileName:Iterator.h
@function: 迭代器抽象类
@author: jaime
@ver: 1.0.0
************************************************************************/
#pragma once
#include <string>
using namespace std;
class Iterator
{
public:
Iterator();
~Iterator();
virtual string First() = 0;
virtual string Next() = 0;
virtual bool isDone() = 0;
virtual string currentItem() = 0;
private:
};
/************************************************************************
@fileName:ConcreteIterator.h
@function: 迭代器具体类
@author: jaime
@ver: 1.0.0
************************************************************************/
#pragma once
#include "Iterator.h"
#include "ConcreteAggregate.h"
class ConcreteIterator : public Iterator
{
public:
ConcreteIterator(ConcreteAggregate* grregate);
~ConcreteIterator();
virtual string First();
virtual string Next();
virtual bool isDone();
virtual string currentItem();
private:
ConcreteAggregate* m_grregate;
int count;
};
#include "ConcreteIterator.h"
ConcreteIterator::ConcreteIterator(ConcreteAggregate* grregate)
:m_grregate(grregate)
{
count = 0;
}
ConcreteIterator::~ConcreteIterator()
{
}
std::string ConcreteIterator::First()
{
return m_grregate->index(0);
}
std::string ConcreteIterator::Next()
{
string ret = "";
count++;
if (count < m_grregate->Count())
{
ret = m_grregate->index(count);
}
return ret;
}
bool ConcreteIterator::isDone()
{
return count < m_grregate->Count() ? true : false;
}
std::string ConcreteIterator::currentItem()
{
return m_grregate->index(count);
}
/************************************************************************
@fileName:Aggregate.h
@function: 聚集抽象类
@author: jaime
@ver: 1.0.0
************************************************************************/
#pragma once
#include "Iterator.h"
class Aggregate
{
public:
Aggregate();
~Aggregate();
virtual Iterator* createIterator() = 0;
private:
};
/************************************************************************
@fileName:ConcreteAggregate.h
@function: 聚集具体类
@author: jaime
@ver: 1.0.0
************************************************************************/
#pragma once
#include "Aggregate.h"
#include <vector>
#include <string>
using namespace std;
class ConcreteAggregate : public Aggregate
{
public:
ConcreteAggregate();
~ConcreteAggregate();
virtual Iterator* createIterator();
int Count();
void push(string str);
string index(int i);
private:
vector<string> m_list;
};
#include "ConcreteAggregate.h"
#include "ConcreteIterator.h"
ConcreteAggregate::ConcreteAggregate()
{
}
ConcreteAggregate::~ConcreteAggregate()
{
}
Iterator* ConcreteAggregate::createIterator()
{
return new ConcreteIterator(this);
}
int ConcreteAggregate::Count()
{
return m_list.size();
}
void ConcreteAggregate::push(string str)
{
m_list.push_back(str);
}
std::string ConcreteAggregate::index(int i)
{
if (i >= 0 && i < m_list.size())
{
return m_list.at(i);
}
}