设计模式(十七):迭代器模式
定义:
- 提供一种方法顺序遍历一个聚集对象,为不同的聚集结构提供遍历所需接口,而不暴露对象内部的表示。
主要解决:
- 不同的方式来遍历整个整合对象
如何解决:
- 把在元素之间游走的责任交给迭代器,而不是聚合对象。
以代码为例
类图关系如下
一、定义Aggregate类
Aggregate为聚合定义了一个接口,它将客户端与对象集合的实现分离开来
#include <iostream>
#include <stdexcept>
#include <vector>
class Iterator;
class ConcreteAggregate;
class Aggregate
{
public:
virtual ~Aggregate() {}
virtual Iterator *createIterator() = 0;
// ...
};
二、定义ConcreteAggregate
Concrete Aggregate具有一组对象,并实现为其集合返回Iterator的方法
class ConcreteAggregate : public Aggregate
{
public:
ConcreteAggregate( const unsigned int size )
{
list = new int[size]();
count = size;
}
~ConcreteAggregate()
{
delete[] list;
}
Iterator *createIterator();
unsigned int size() const
{
return count;
}
int at( unsigned int index )
{
return index;
}
// ...
private:
int *list;
unsigned int count;
// ...
};
三、定义Iterator
Iterator提供了所有迭代器必须实现的接口和一组遍历元素的方法
class Iterator
{
public:
virtual ~Iterator() { /* ... */ }
virtual void first() = 0;
virtual void next() = 0;
virtual bool isDone() const = 0;
virtual int currentItem() const = 0;
// ...
};
四、定义ConcreteIterator
Concrete Iterator实现接口,负责管理迭代器的当前位置
class ConcreteIterator : public Iterator
{
public:
ConcreteIterator( ConcreteAggregate *l ) :
list( l ), index( 0 ) {}
~ConcreteIterator() {}
void first()
{
index = 0;
}
void next()
{
index++;
}
bool isDone() const
{
return ( index >= list->size() );
}
int currentItem() const
{
if ( isDone() )
{
return -1;
}
return list->at(index);
}
// ...
private:
ConcreteAggregate *list;
unsigned int index;
// ...
};
五、main函数的调用
Iterator *ConcreteAggregate::createIterator()
{
return new ConcreteIterator( this );
}
int main()
{
unsigned int size = 5;
ConcreteAggregate list = ConcreteAggregate( size );
Iterator *it = list.createIterator();
for ( ; !it->isDone(); it->next())
{
std::cout << "Item value: " << it->currentItem() << std::endl;
}
delete it;
return 0;
}
运行结果:
Item value: 0
Item value: 1
Item value: 2
Item value: 3
Item value: 4
这样简单实现了一个迭代器模式
迭代器模式优缺点
优点:
1、它支持以不同的方式遍历一个聚合对象。
2、迭代器简化了聚合类。
3、在同一个聚合上可以有多个遍历。
4、在迭代器模式中,增加新的聚合类和迭代器类都很方便,无须修改原有代码
缺点:
1、由于迭代器模式将存储数据和遍历数据的职责分离,增加新的聚合类需要对应增加新的迭代器类,类的个数成对增加,这在一定程度上增加了系统的复杂性。
注意事项:
- 迭代器模式分离了对象的遍历行为,既不暴露内部结构又可以让外部代码透明的访问集合内部的数据。