首页 > 代码库 > 迭代器模式

迭代器模式

定义

迭代器模式(Iterator Pattern)提供一种方法访问一个容器对象中各个元素,而又不需暴露该对象内部细节。

迭代器模式通用类图

image

Iterator抽象迭代器

抽象迭代器负责定义访问和遍历元素的接口,而且基本上是有固定的3个方法:First()获取第一个元素,Next()访问下一个元素,IsDone()是否已经访问到底部。

ConcreteIterator具体迭代器

具体迭代器角色要实现迭代器接口,完成容器元素的遍历。

Aggregate抽象容器

负责提供创建具体迭代器角色的接口,必然提供一个类似CreateIterator()这样的方法。

ConcreteAggregate具体容器

实现容器接口定义的方法,创建出容纳迭代器的对象。

C++通用源码

实际上在C++的标准模板库(STL)中已经实现了各种容器和迭代器(其他语言一般也都有自己的STL),很多时候只需直接使用而不需要自己来实现迭代器类型的定义。所以就不举具体的例子了,只是实现一段通用源码。

#include <iostream>     // std::cout
#include <vector>
#include <string>
using namespace std;
class Object{
    string str;
public:
    Object(const char *s):str(s){};
    Object(string s):str(s){};
    friend ostream & operator << (ostream &os,const Object &obj);
};
ostream & operator << (ostream &os,const Object &obj)
{
    os<<obj.str;
    return os;
}
template <typename class_type>
class Iterator{
public:
    Iterator(){};
    virtual class_type * First()=0;     //第一个元素
    virtual class_type * Next()=0;      //下一个
    virtual bool IsDone()=0;            //是否遍历到结尾
    virtual class_type * CurrentItem()=0;   //获取当前元素
    virtual ~Iterator(){};
};

template <typename T> class ConcreteIterator;

template <typename class_type>
class Aggregate{
public:
    virtual Iterator<class_type>* CreateIterator()=0;
    virtual ~Aggregate(){};
};

template <typename class_type>
class ConcreteAggregate:public Aggregate<class_type>{
private:
    vector<class_type *> container;
public:
    ConcreteAggregate(){};
    ~ConcreteAggregate(){};
    Iterator<class_type>* CreateIterator(){
        return new ConcreteIterator<class_type>(this);
    };
    class_type* At(unsigned int index){
        if(index>=0 && index<container.size())
            return container[index];
        else
            return NULL;
    }
    void Add(class_type *object){
        container.push_back(object);
    }
    int Count(){
        return container.size();
    }
};

template <typename class_type>
class ConcreteIterator:public Iterator<class_type>{
private:
    ConcreteAggregate<class_type> * ca;
    int current;
public:
    ConcreteIterator(ConcreteAggregate<class_type> *a):ca(a),current(0){};
    class_type * First(){
        return ca->At(current=0);
    }
    class_type * Next(){
        return ca->At(++current);
    }
    bool IsDone(){
        return current>=ca->Count()? true:false;
    }
    class_type *CurrentItem(){
        return ca->At(current);
    }
    ~ConcreteIterator(){};
};

int main () {
    ConcreteAggregate<Object> Container;
    Object *ob= new Object("让海天为我聚能量");
    Container.Add(ob);
    ob = new Object("去开天辟地为我理想去闯");
    Container.Add(ob);
    ob = new Object("看碧波高壮");
    Container.Add(ob);
    ob = new Object("又看碧空广阔浩气扬");
    Container.Add(ob);
    ob = new Object("既是男儿当自强");
    Container.Add(ob);

    Iterator<Object> *it = Container.CreateIterator();

    while(!it->IsDone())
    {
        cout<<*(it->CurrentItem())<<endl;
        it->Next();
    }

    it->First();
    while(!it->IsDone())
    {
        delete it->CurrentItem();
        it->Next();
    }
    delete it;
    return 0;
}

运行结果

image