迭代器我们都用过,不管是C++,PHP等等,它们是标准库给我们实现好的,通过它能访问像vector, list这样的容器。如果我们自己有一个对象集合,你也想提供这样的接口,那就要自己实现。
迭代器模式:使用迭代器模式来提供对聚合对象的统一存取,即提供一个外部的迭代器来对聚合对象进行访问和遍历 , 而又不需暴露该对象的内部结构。
如果不用该模式,你可以在聚合对象中添加遍历的函数,这增加了聚合对象的复杂性,遍历的时候还要记住此时状态,如果同时进行了添加、删除操作,这个状态也就改变了。程序容易出错;如果把遍历的代码交由用户来完成,这暴露了聚合对象的细节,一旦聚合对象接口变化,比如vector变成map,用户代码也要修改。这时候,你可能就想到要把数据和操作分离了,对,就是这个味!Iterator类屏蔽了对聚合对象的操作细节,对用户提供一个统一的接口。
typedef int Object;
class Iterator;
class Aggregate {
public:
virtual Iterator* CreateIterator() = 0;
virtual Object GetItem(int dix) = 0;
virtual int GetSize() = 0;
};
class ConcreteAggregate :public Aggregate {
public:
Iterator* CreateIterator();
Object GetItem(int idx);
int GetSize();
private:
vector<Object> _objs;
};
Iterator* ConcreteAggregate::CreateIterator()
{
return new ConcreteIterator(this);
}
Object ConcreteAggregate::ConcreteAggregate::GetItem(int idx)
{
if (idx < this->GetSize())
return _objs[idx];
else
return -1;
}
int ConcreteAggregate::GetSize() {
return _objs.size();
}
typedef int Object;
class Aggregate;
class Iterator {
public:
virtual void first() = 0;
virtual void next() = 0;
virtual bool end() = 0;
virtual Object current() = 0;
};
class ConcreteIterator : public Iterator {
public:
ConcreteIterator(Aggregate*, int idx=0);
void first();
void next();
bool end();
Object current();
private:
Aggregate* _agg;
int _idx;
};
ConcreteIterator::ConcreteIterator(Aggregate* agg, int idx)
{
_agg = agg;
_idx = _idx;
}
void ConcreteIterator::first()
{
_idx = 0;
}
void ConcreteIterator::next()
{
if (_idx < _agg->GetSize())
_idx++;
}
bool ConcreteIterator::end()
{
return (_idx == _agg->GetSize());
}
Object ConcreteIterator::current()
{
return _agg->GetItem(_idx);
}
int main()
{
Aggregate* agg = new ConcreteAggregate();
Iterator* it = new ConcreteIterator(agg);
for (it->first(); !it->end(); it->next())
{
cout << it->current() << " " << endl;
}
return 0;
}
这里,聚合对象里没有值,所以打印为空,只是做个示例!
该模式的好处不在于它能遍历对象,而在于可以为不同的聚合对象提供不同的统一的接口:一个聚合对象可以有多种不同的遍历方式;多个聚合对象也可以采用一种遍历方式。为了简单,上面的UML图中二者继承出的具体类都只画了一个。如果增加了聚合对象,而当前存在的迭代器不支持,新增也很容易,满足开闭原则。
由于迭代器模式将存储数据和遍历数据的职责分离,增加新的聚合类很可能需要对应增加新的迭代器类,类的个数成对增加,这在一定程度上增加了系统的复杂性。
Composite :迭代器常被应用到象复合这样的递归结构上。
Factory Method:多态迭代器靠Factory Method来例化适当的迭代器子类。
Memento:常与迭代器模式一起使用。迭代器可使用一个 Memento来捕获一个迭代的状态。迭代器在其内部存储Memento。