前言
尊重原创,本系列文本解析部分主要基于Candidate for Master’s Degree School of Computer Wuhan University的K_Eckel([email protected] )《设计模式精解-GoF 23 种设计模式解析附 C++实现源码》。为了避免重造轮子,本系列博文对源码在ubuntu16.04下做了验证并上传到了gitee ,再次感谢。
如有问题,可邮件联系我([email protected] )并共同探讨解决方案。
目录
创建型模式(Creating Pattern)
Factory 模式 | AbstactFactory 模式 | Singleton 模式 | Builder 模式 | Prototype 模式
结构型模式(Structrual Pattern)
Bridge 模式 | Adapter 模式 | Decorator 模式 | Composite 模式 | Flyweight 模式 | Facade 模式 | Proxy 模式
行为型模式(Behavioral Pattern)
Template 模式 | Strategy 模式 | State 模式 | Observer 模式 | Memento 模式 | Mediator 模式 | Command 模式 | Visitor 模式 | Iterator 模式 | Interpreter 模式 | Chain of Responsibility 模式
Iterator 模式简介:
迭代器模式(Iterator Pattern)是 Java 和 .Net 编程环境中非常常用的设计模式。这种模式用于顺序访问集合对象的元素,不需要知道集合对象的底层表示。从而访问一个聚合对象的内容而无须暴露它的内部表示。
问题
迭代器模式应该是最为熟悉的模式了,最简单的证明就是我在实现Composite模式 、Flyweight模式 、Observer模式 中就直接用到了STL提供的Iterator来遍历Vector或者List数据结构。
Iterator模式也正是用来解决对一个聚合对象的遍历问题,将对聚合的遍历封装到一个类中进行,这样就避免了暴露这个聚合对象的内部表示的可能。
模式选择
Iterator模式典型的结构图为:
图 1:Iterator 模式结构示意图
实现
完整代码示例(code)
Iterator模式的实现比较简单,这里为了方便初学者的学习和参考,将给出完整的实现代码(所有代码采用 C++实现,并在 Visual Studio Code,Version: 1.36.1 下测试运行)。
源码gitee地址:点击这里
代码目录结构:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 PS C:\Users\guopz\Desktop\GiteeBlog\designpatternsbycpipei\behavioralPattern\Iterator> tree /F 卷 Windows 的文件夹 PATH 列表 卷序列号为 F0C5-AFA6 C:. ├─include │ Aggregate.h │ Iterator.h │ └─src a.out Aggregate.cpp Iterator.cpp main.cpp PS C:\Users\guopz\Desktop\GiteeBlog\designpatternsbycpipei\behavioralPattern\Iterator>
Aggregate.h:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 // Aggregate.h #ifndef _AGGREGATE_H_ #define _AGGREGATE_H_ class Iterator; typedef int Object; class Aggregate { private: /* data */ protected: Aggregate(/* args */); public: virtual ~Aggregate(); virtual Iterator* CreateIterator() = 0; virtual Object GetItem(int idx) = 0; virtual int GetSize() = 0; }; class ConcreteAggregate : public Aggregate { public: enum { SIZE = 3 }; ConcreteAggregate(/* args */); ~ConcreteAggregate(); Iterator* CreateIterator(); Object GetItem(int idx); int GetSize(); private: Object _objs[SIZE]; }; #endif //~_AGGREGATE_H_
Iterator.h:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 // Iterator.h #ifndef _ITERATOR_H_ #define _ITERATOR_H_ class Aggregate; typedef int Object; class Iterator { private: /* data */ protected: Iterator(/* args */); public: ~Iterator(); virtual void First() = 0; virtual void Next() = 0; virtual bool IsDone() = 0; virtual Object CurrentItem() = 0; }; class ConcreteIterator : public Iterator { private: Aggregate* _ag; int _idx; public: ConcreteIterator(Aggregate* ag, int idx = 0); ~ConcreteIterator(); void First(); void Next(); bool IsDone(); Object CurrentItem(); }; #endif //~_ITERATOR_H_
Aggregate.cpp:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 // Aggregate.cpp #include "../include/Aggregate.h" #include <iostream> #include "../include/Iterator.h" using namespace std; Aggregate::Aggregate(/* args */) {} Aggregate::~Aggregate() {} ConcreteAggregate::ConcreteAggregate(/* args */) { 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.cpp:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 // Iterator.cpp #include "../include/Iterator.h" #include <iostream> #include "../include/Aggregate.h" using namespace std; Iterator::Iterator(/* args */) {} 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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 // main.cpp #include "../include/Iterator.h" #include <iostream> #include "../include/Aggregate.h" 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
私有数据和方法的机会。
编译运行结果:
1 2 3 4 5 6 PS C:\Users\guopz\Desktop\GiteeBlog\designpatternsbycpipei\behavioralPattern\Iterator\src> g++ *.cpp -std=c++11 PS C:\Users\guopz\Desktop\GiteeBlog\designpatternsbycpipei\behavioralPattern\Iterator\src> .\a.exe 0 1 2 PS C:\Users\guopz\Desktop\GiteeBlog\designpatternsbycpipei\behavioralPattern\Iterator\src>
讨论
Iterator模式的应用很常见,我们在开发中就经常会用到STL中预定义好的Iterator
来对STL类进行遍历(Vector
、Set
等)。