前言

尊重原创,本系列文本解析部分主要基于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模式典型的结构图为:
Iterator Pattern
图 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的状态,我们可以尽量减小Aggregatepublic接口,而通过将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类进行遍历(VectorSet等)。