Iterator设计模式

    技术2022-05-19  23

    Iterator模式应该是最为熟悉的模式了,最简单的证明就是我在实现Composite模式、Flyweight模式、Observer模式中就直接用到了STL提供的Iterator来遍历Vector或者List数据结构。

    Iterator模式也正是用来解决对一个聚合对象的遍历问题,将对聚合的遍历封装到一个类中进行,这样就避免了暴露这个聚合对象的内部表示的可能。

     Iterator几乎是大部分人在初学C++的时候就无意之中接触到的第一种设计模式,因为在STL之中,所有的容器类都有与之相关的迭代器.以前初学STL时,常看到讲述迭代器作用的时候说:提供一种方式,使得算法和容器可以独立的变化,而且在访问容器对象的时候不必暴露容器的内部细节,具体是怎么做到这一点的呢?

       在STL的实现中,所有的迭代器(Iterator)都必须遵照一套规范,这套规范里面定义了几种类型的名称,比如对象的名称,指向对象的指针的名称,指向对象的引用的名称...等等,当新生成一个容器时与之对应的Iterator都要遵守这个规范里面所定义的名称,这样在外部看来虽然里面的实现细节不一样,但是作用(也就是对外的表象)都是一样的,通过某个名称可以得到容器包含的对象,通过某个名称可以得到容器包含的对象的指针等等的.而且,采用这个模式把访问容器的重任都交给了具体的iterator类中.于是,在使用Iterator来访问容器对象的算法不需要知道需要处理的是什么容器,只需要遵守事先约定好的Iterator的规范就可以了;而对于各个容器类而言,不管内部的事先如何,是树还是链表还是数组,只需要对外的接口也遵守Iterator的标准,这样算法(Iterator的使用者)和容器(Iterator的提供者)就能很好的进行合作,而且不必关心对方是如何事先的,简而言之,Iterator就是算法和容器之间的一座桥梁.  //Aggregate.h #ifndef _AGGREGATE_H_ #define _AGGREGATE_H_ class Iterator; typedef int Object; class Interator; class Aggregate { public: virtual ~Aggregate(); virtual Iterator* CreateIterator() = 0; virtual Object GetItem(int idx) = 0; virtual int GetSize() = 0; protected: Aggregate(); private: }; class ConcreteAggregate : public Aggregate { public: enum {SIZE = 3}; ConcreteAggregate(); ~ConcreteAggregate(); Iterator* CreateIterator(); Object GetItem(int idx); int GetSize(); protected: private: Object _objs[SIZE]; }; #endif //~_AGGREGATE_H_    //Aggregate.cpp #include "Aggregate.h" #include "Iterator.h" #include <iostream> using namespace std; Aggregate::Aggregate() { } Aggregate::~Aggregate() { } ConcreteAggregate::ConcreteAggregate() { for (int i = 0; i < SIZE; i++) _objs[i] = i; } ConcreteAggregate::~ConcreteAggregate() { } Iterator* ConcreteAggregate::CreateIterator() { return new ConcreteIterator(this); } Object ConcreteAggregate::GetItem(int idx) { if (idx < this->GetSize()) return _objs[idx]; else return -1; } int ConcreteAggregate::GetSize() { return SIZE; }   //Iterator.h #ifndef _ITERATOR_H_ #define _ITERATOR_H_ class Aggregate; typedef int Object; class Iterator { public: virtual ~Iterator(); virtual void First() = 0; virtual void Next() = 0; virtual bool IsDone() = 0; virtual Object CurrentItem() = 0; protected: Iterator(); private: }; class ConcreteIterator:public Iterator { public: ConcreteIterator(Aggregate* ag , int idx = 0); ~ConcreteIterator(); void First(); void Next(); bool IsDone(); Object CurrentItem(); protected: private: Aggregate* _ag; int _idx; }; #endif //~_ITERATOR_H_   //Iterator.cpp #include "Iterator.h" #include "Aggregate.h" #include <iostream> using namespace std; Iterator::Iterator() { } Iterator::~Iterator() { } ConcreteIterator::ConcreteIterator(Aggregate* ag , int idx) { this->_ag = ag; this->_idx = idx; } ConcreteIterator::~ConcreteIterator() { } Object ConcreteIterator::CurrentItem() { return _ag->GetItem(_idx); } void ConcreteIterator::First() { _idx = 0; } void ConcreteIterator::Next() { if (_idx < _ag->GetSize()) _idx++; } bool ConcreteIterator::IsDone() { return (_idx == _ag->GetSize()); }   //main.cpp #include "Iterator.h" #include "Aggregate.h" #include <iostream> using namespace std; int main(int argc,char* argv[]) { Aggregate* ag = new ConcreteAggregate(); Iterator* it = new ConcreteIterator(ag); for (; !(it->IsDone()) ; it->Next()) { cout<<it->CurrentItem()<<endl; } return 0; }   Iterator模式的实现代码很简单,实际上为了更好地保护Aggregate的状态,我们可以尽量减小Aggregate的public接口,而通过将Iterator对象声明位Aggregate的友元来给予Iterator一些特权,获得访问Aggregate私有数据和方法的机会。

    本文来自博客,转载请标明出处:http://blog.csdn.net/armman/archive/2007/04/08/1556391.aspx


    最新回复(0)