迭代器模式(Iterator)

迭代器模式(Iterator

 

迭代器模式(Iterator[Cursor]

意图:提供一种方法顺序访问一个聚合对象中的每个元素,而又不想暴露该对象的内部表示。

应用STL标准库迭代器实现、Java集合类型迭代器等

模式结构

心得

迭代器模式的目的是在不获知集合对象内部细节的同时能对集合元素进行遍历操作,单纯依靠集合对象内部提供遍历操作会将对象结构复杂化。另外,对象如果支持多种遍历方式,那么对象的成员函数会变得多而复杂。解决这种问题最好的方式是将这些变化封装在一个统一的对象中——Iterator,迭代其对象提供了迭代操作所必需的基本接口:初始化、递增操作、结束条件、返回当前元素[有点类似for循环的语法元素]。这样,不管对象需要什么样的遍历方式,或者需要多少种遍历方式,只需要构造相应的迭代器类就可以了,用迭代器访问集合对象,进行遍历操作。具体迭代器对象(ConcreteIterator)和具体集合对象(Aggregate)是一种强耦合关系,一般迭代器都会包含一个对具体对象的引用或指针。而具体集合对象一般都会提供创建具体迭代器对象的工厂方法——createIterator。迭代器通过访问具体集合对象的基本接口来实现具体的遍历接口。用户需要遍历集合对象内容的话,只需要构造相应的迭代其对象就可以了。

举例

按照上述设计,我们实现一个简单的列表迭代器,这里使用了C++模板来构建类型无关代码。

//类提前声明
template<class Item>
class Aggregate;
//迭代器接口
template<class Item>
class Iterator
{
public:
    virtual void first()=0;
    virtual void next()=0;
    virtual Item* currentItem()=0;
    virtual bool isDone()=0;
    virtual ~Iterator(){}
};
//类提前声明
template<class Item>
class ConcreteAggregate;
//具体迭代器
template<class Item>
class ConcreteIterator:public Iterator<Item>
{
    ConcreteAggregate<Item>*aggr;
    int cur;
public:
    ConcreteIterator(ConcreteAggregate<Item>*a):aggr(a),cur(0){}
    virtual void first()
    {
        cur=0;
    }
    virtual void next()
    {
        if(cur<aggr->getLen())
            cur++;
    }
    virtual Item* currentItem()
    {
        if(cur<aggr->getLen())
            return &(*aggr)[cur];
        else
            return NULL;
    }
    virtual bool isDone()
    {
        return (cur>=aggr->getLen());
    }
};
//抽象集合类
template<class Item>
class Aggregate
{
public:
    virtual Iterator<Item>* createIterator()=0;
    virtual ~Aggregate(){}
};
//具体集合类
template<class Item>
class ConcreteAggregate:public Aggregate<Item>
{
    vector<Item>data;
public:
    ConcreteAggregate()
    {
        data.push_back(1);
        data.push_back(2);
        data.push_back(3);
    }
    virtual Iterator<Item>* createIterator()
    {
        return new ConcreteIterator<Item>(this);
    }
    Item& operator[](int index)
    {
        return data[index];
    }
    int getLen()
    {
        return data.size();
    }
};

用户进行遍历操作的代码一般是:

Aggregate<int> * aggr =new ConcreteAggregate<int>();
Iterator<int> *it=aggr->createIterator();
//遍历操作
for(it->first();!it->isDone();it->next())
{
    cout<<*(it->currentItem())<<endl;
}
delete it;
delete aggr;

只要用户构造好集合对象,直接用工厂方法生成迭代器进行遍历即可,至于是哪个具体的迭代器,以及迭代器的内部实现,使用者不用关心。

参考文章http://www.cnblogs.com/jqbird/archive/2011/08/31/2160653.html

posted @ 2012-12-14 23:53  Florian  阅读(1289)  评论(0编辑  收藏  举报