【转】设计模式学习笔记(16)-迭代器
迭代器(Iterator)模式是一个很小的模式,但却十分常用。迭代器模式在组合数据类型中用得比较多,如链表、数组、图等等。在这些数据结构中,由于各自的结构差距巨大,导致遍历等操作大相径庭。数组的遍历十分简单,一个循环就能搞定;而图的便利则比较复杂,有DFS,BFS等算法。而我们有的程序则根本不想知道是怎么遍历,如统计元素的个数等操作。怎么办?
我们很容易想到,如果将遍历操作抽象出来,放在单独的一个类中,不同的数据结构需要实现此类,然后我们只要调用公共接口操作就行了。这个接口就是迭代器。
Iterator是这个类图的核心,定义了访问和遍历元素的接口。ConcreteIterator是ConcreteAggregate产生的迭代器类,他继承于Iterator接口。ConcreteAggregate是具体的聚合类,如数组、链表等。
下面我们来写一个简单的Iterator:
这是定义Iterator接口
|
1
2
3
4
5
6
7
8
9
|
template<typename T>class Iterator {public: virtual void First() = 0; virtual void Next() = 0; virtual bool IsDone() = 0; virtual T CurrentItem() = 0;}; |
定义一个Iterator的实现类,它是由List类生成的
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
class List;template<typename T>class ListIterator : public Iterator<T> {private: int count; List* _list;public: ListIterator<T>(List* list) : _list(list),count(0) {} void First(){ count = 0; } void Next(){ count++; } bool IsDone(){ return count >= 10; } T CurrentItem(){ return _list->_a[count]; }}; |
这个List写得很简单了,只有一个10个元素数组,然后初始化的时候填入0~9。其中CreateIterator返回一个可用的迭代器。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
class List {private: int _a[10];public: friend class ListIterator<int>; List(){ for(int i = 0; i < 10; i++) _a[i] = i; } Iterator<int>* CreateIterator(){ return new ListIterator<int>(this); }}; |
最后我们在主方法里写道:
|
1
2
3
4
5
|
List list;Iterator<int>* itr = list.CreateIterator();cout << itr->CurrentItem() << endl;itr->Next();cout << itr->CurrentItem() << endl; |
最终输出
|
1
2
|
01 |
这正是我们想要的结果。
从上例可以看出,从对外接口来看,我们拥有迭代器就能够完全掌握对List的操作,而不用知道List里面到底是怎样组合数据的,是使用数组还是链表我们不用关心,这样就将实现与表示分离了,减少了耦合度。
当然迭代器的功能还可以更强大,如提供向前移动、删除元素、增加元素等,可根据实际情况自行决定。
最后来看看迭代器模式的适用性:
- 访问一个聚合对象的内容而无需暴露它的内部表示
- 支持对聚合对象的多种遍历
- 为遍历不同的聚合结构提供一个统一的接口(即,支持多态迭代)
迭代器模式在面向对象系统中十分普遍,如Java Collection包中几乎所有的集合类都实现了Iterator接口,这样就将内部实现完全隐藏起来,降低了耦合度。
posted on 2013-03-05 16:23 TheKingOfKingFish 阅读(100) 评论(0) 收藏 举报

浙公网安备 33010602011771号