问题聚焦:
当我们在KTV唱歌的时候,会使用控制系统进行切歌、选中、删除、插到队首等功能,而这是我们无需知道歌曲在曲库中是如何存放的。
这便是迭代器模式的思想:提供一种方法访问一个聚合对象中各个元素,而又不暴露该对象的内部表示。
对于迭代器我们并不陌生,C++标准库中的容器都提供了迭代器访问模式。当我们自定义某些聚合型类提供给客户使用的时候,并不希望暴露对象内部的构造,这时定义一个迭代器是比较好的解决方案。
思想:
对聚合类(如列表)的访问和遍历从列表对象中分离出来,并放入一个迭代器对象中
迭代器定义了一个访问该列表元素的接口,迭代器负责跟踪当前的元素,即知道哪些元素已经遍历过了,如下图所示:
多态迭代:
列表对象负责创建相应的迭代器
结构:
参与者:
- 迭代器角色(Iterator):迭代器角色负责定义访问和遍历元素的接口。
- 具体迭代器角色(Concrete Iterator):具体迭代器角色要实现迭代器接口,并要记录遍历中的当前位置。
- 集合角色(Aggregate):集合角色负责提供创建具体迭代器角色的接口。
- 具体集合角色(Concrete Aggregate):具体集合角色实现创建具体迭代器角色的接口——这个具体迭代器角色于该集合的结构相关。
- 支持以不同的方式遍历一个集合
- 迭代器简化了聚合的接口
- 在同一个集合上可以有多个遍历
Demo
迭代器模式示例
模拟KTV点歌系统
功能:切歌,选中,插入到队首等功能
一般来说,迭代器尽量不要改变所遍历的聚类,所以在这个例子中,只提供遍历功能
/*** 迭代器类声明定义 ***/
template <typename Item>
class Iterator
{
public:
virtual Item* first() = 0;
virtual Item* next() = 0;
//virtual void toTop(Item* ) = 0;
virtual Item* currentItem() = 0;
virtual bool isDone() = 0;
virtual ~Iterator() {};
};
template <typename Item>
class KtvCrlor : public Iterator<Item>
{
public:
KtvCrlor(SongsBook<Item>* songsbook) : songsbook(songsbook), index(0) { }
virtual Item* first();
virtual Item* next();
virtual Item* currentItem();
virtual bool isDone();
private:
SongsBook<Item>* songsbook;
int index;
};
/*** 聚类声明定义 ***/
template<typename Item>
class Aggregate
{
public:
Aggregate<Item>() {};
virtual Iterator<Item>* createIterator() = 0;
virtual ~Aggregate() {};
};
template<typename Item>
class SongsBook : public Aggregate<Item>
{
public:
SongsBook<Item>() : Aggregate<Item>() { };
void addSong(Item* song);
int count();
virtual Iterator<Item>* createIterator();
Item* operator[](int index);
private:
std::vector<Item*> songs;
};
使用:
#include "ktv.h"
#include<string>
int main()
{
SongsBook<std::string>* songsbook = new SongsBook<std::string>();
Iterator<std::string>* ktvController = songsbook->createIterator();
/* 选中歌曲 */
std::cout << "请选择歌曲" << std::endl;
songsbook->addSong(new std::string("春天里"));
songsbook->addSong(new std::string("生如夏花"));
songsbook->addSong(new std::string("我是一棵秋天的树 "));
songsbook->addSong(new std::string("冬天里的一把火"));
/* 遍历曲库 */
std::cout << std::endl;
std::cout << "当前列表中包含歌曲: " << songsbook->count() << "首" << std::endl;
while(!ktvController->isDone()) {
std::cout << *ktvController->next() << std::endl;
}
system("Pause");
}
运行截图:
编译环境:VS2010
参考资料:
《设计模式:可复用面向对象软件的基础》
http://blog.csdn.net/lcl_data/article/details/9310313 我所理解的设计模式(C++实现)——迭代器模式(Iterator Pattern)