设计模式学习笔记--迭代器模式
2017-08-19 12:06
495 查看
版权声明:欢迎转载,共同进步。请注明出处:http://blog.csdn.net/puppet_master
目录(?)[+]
我们很多时候都是在处理一组对象,相对的,我们就需要相应的管理容器类来存储对象,.我们需要Add,Remove等方法,但是我们还需要相应的方法来访问容器内的对象。比如获得首个对象First,尾部对象End,下一个对象Next等等方法。如果我们把这些方法都放在容器内实现的话,容器的职责就过重了,而且迭代的方式有所不同,比如我们需要从前向后迭代或者从后向前迭代,我们就可以直接通过更换迭代器来达到不同的效果。通过将迭代部分的内容抽离,我们就可以获得更加灵活的对象访问形式。
下面我们来看一下迭代器模式的定义以及UML类图:
迭代器模式(Iterator Pattern):提供一种方法来访问聚合对象,而不用暴露这个对象的内部表示,其别名为游标(Cursor)。迭代器模式是一种对象行为型模式。
分析一下UML图,我们的容器类就相当于Aggregate,提供一些抽象的容器方法,抽象迭代器类定义了一些迭代方法,比如获得首尾元素,下个元素,当前元素等等,但是具体的迭代方式是通过ConcreteIterator实现的。具体容器类ConcreteAggregate类作为迭代器工厂,可以创建一个本容器对应的迭代器。
[cpp] view
plain copy
// Design Pattern.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#include <string>
#include <vector>
#include <map>
using namespace std;
//迭代器基类
class Iterator
{
public:
//迭代器向后指向一个
virtual void Next() = 0;
//迭代器指向首元素
virtual void Begin() = 0;
//迭代器是否指向容器末尾
virtual bool IsEnd() = 0;
//返回当前迭代器所指元素
virtual string GetCurrent() = 0;
};
//容器基类
class VecterBase
{
public:
//添加元素
virtual void Add(string elem) = 0;
//获得当前元素
virtual string Get(int index) = 0;
//获得容器当前容量
virtual int Count() = 0;
//迭代器工厂
virtual Iterator* CreateIterator() = 0;
};
//具体迭代器类
class ConcreteIterator : public Iterator
{
private:
int m_currentIndex;
VecterBase* m_vec;
public:
ConcreteIterator(VecterBase* vec)
:m_vec(vec)
,m_currentIndex(0)
{
}
virtual void Next() override
{
m_currentIndex++;
}
virtual void Begin()
{
m_currentIndex = 0;
}
virtual bool IsEnd()
{
return m_currentIndex >= m_vec->Count();
}
virtual string GetCurrent()
{
return m_vec->Get(m_currentIndex);
}
};
//具体容器类
class ConcreteVector : public VecterBase
{
private:
vector<string> stringvec;
public:
void Add(string elem)
{
stringvec.push_back(elem);
}
string Get(int index)
{
return stringvec[index];
}
int Count()
{
return stringvec.size();
}
Iterator* CreateIterator()
{
return new ConcreteIterator(this);
}
};
int _tmain(int argc, TCHAR* argv[])
{
VecterBase* vec = new ConcreteVector();
vec->Add("张三");
vec->Add("李四");
vec->Add("王二麻子");
Iterator* it = vec->CreateIterator();
for (it->Begin(); !it->IsEnd(); it->Next())
{
cout << it->GetCurrent() << endl;
}
//是不是很像STL里面的迭代器呢?
/*for (std::vector<string>::iterator it = vec.begin(); it != vec.end(); ++it)
{
cout << (*it) << endl;
}*/
system("pause");
return 0;
}
结果:
张三
李四
王二麻子
请按任意键继续. . .
我们简单来看一下迭代器,我这里写了一段STL的迭代器代码作为对比,我们的迭代器用法与STL的基本相同。首先创建一个迭代器,初值为容器首元素位置,然后进行迭代,直到到达尾元素为止。每次迭代向后移动一个元素。
优点:
1)迭代器简化了容器类,实现了单一职责原则。将遍历和存储功能分离,不论是新增容器类型还是新增迭代器都符合开放-封闭原则。
2)可以提供多种迭代方式,比如新增一个从后向前迭代的迭代器等。
缺点:
1)迭代器的设计比较难,很难抽象出一套比较完整的迭代器基类。
2)迭代器使系统类个数增加,一定程度上难以理解。
使用时机:
1)访问一个聚合对象的内容而无须暴露它的内部表示。将聚合对象的访问与内部数据的存储分离,使得访问聚合对象时无须了解其内部实现细节。
2) 需要为一个聚合对象提供多种遍历方式。
3) 为遍历不同的聚合结构提供一个统一的接口,在该接口的实现类中为不同的聚合结构提供不同的遍历方式,而客户端可以一致性地操作该接口。
最后,顺带提一句,迭代器模式太有用了,以至于语言或者基础库都提供了完整的迭代器实现,反倒这个模式我们自己实现的意义不大了....
目录(?)[+]
一.简介
今天学习一下设计模式中的迭代器模式,迭代器模式是一种非常非常常用的设计模式,以至于太有用了,C#,Java都将其作为内置实现,C++也提供了STL的迭代器,我们每天都在用,却反倒感觉迭代器模式没那么重要了。毕竟我们自己实现的迭代器还是比不上语言原生提供的实现,但是为了学习,我们还是要看一下迭代器模式的实现,只有了解了原理,才能更好地使用。我们很多时候都是在处理一组对象,相对的,我们就需要相应的管理容器类来存储对象,.我们需要Add,Remove等方法,但是我们还需要相应的方法来访问容器内的对象。比如获得首个对象First,尾部对象End,下一个对象Next等等方法。如果我们把这些方法都放在容器内实现的话,容器的职责就过重了,而且迭代的方式有所不同,比如我们需要从前向后迭代或者从后向前迭代,我们就可以直接通过更换迭代器来达到不同的效果。通过将迭代部分的内容抽离,我们就可以获得更加灵活的对象访问形式。
下面我们来看一下迭代器模式的定义以及UML类图:
迭代器模式(Iterator Pattern):提供一种方法来访问聚合对象,而不用暴露这个对象的内部表示,其别名为游标(Cursor)。迭代器模式是一种对象行为型模式。
分析一下UML图,我们的容器类就相当于Aggregate,提供一些抽象的容器方法,抽象迭代器类定义了一些迭代方法,比如获得首尾元素,下个元素,当前元素等等,但是具体的迭代方式是通过ConcreteIterator实现的。具体容器类ConcreteAggregate类作为迭代器工厂,可以创建一个本容器对应的迭代器。
二.迭代器模式的例子
我们直接看一下迭代器模式的例子:[cpp] view
plain copy
// Design Pattern.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#include <string>
#include <vector>
#include <map>
using namespace std;
//迭代器基类
class Iterator
{
public:
//迭代器向后指向一个
virtual void Next() = 0;
//迭代器指向首元素
virtual void Begin() = 0;
//迭代器是否指向容器末尾
virtual bool IsEnd() = 0;
//返回当前迭代器所指元素
virtual string GetCurrent() = 0;
};
//容器基类
class VecterBase
{
public:
//添加元素
virtual void Add(string elem) = 0;
//获得当前元素
virtual string Get(int index) = 0;
//获得容器当前容量
virtual int Count() = 0;
//迭代器工厂
virtual Iterator* CreateIterator() = 0;
};
//具体迭代器类
class ConcreteIterator : public Iterator
{
private:
int m_currentIndex;
VecterBase* m_vec;
public:
ConcreteIterator(VecterBase* vec)
:m_vec(vec)
,m_currentIndex(0)
{
}
virtual void Next() override
{
m_currentIndex++;
}
virtual void Begin()
{
m_currentIndex = 0;
}
virtual bool IsEnd()
{
return m_currentIndex >= m_vec->Count();
}
virtual string GetCurrent()
{
return m_vec->Get(m_currentIndex);
}
};
//具体容器类
class ConcreteVector : public VecterBase
{
private:
vector<string> stringvec;
public:
void Add(string elem)
{
stringvec.push_back(elem);
}
string Get(int index)
{
return stringvec[index];
}
int Count()
{
return stringvec.size();
}
Iterator* CreateIterator()
{
return new ConcreteIterator(this);
}
};
int _tmain(int argc, TCHAR* argv[])
{
VecterBase* vec = new ConcreteVector();
vec->Add("张三");
vec->Add("李四");
vec->Add("王二麻子");
Iterator* it = vec->CreateIterator();
for (it->Begin(); !it->IsEnd(); it->Next())
{
cout << it->GetCurrent() << endl;
}
//是不是很像STL里面的迭代器呢?
/*for (std::vector<string>::iterator it = vec.begin(); it != vec.end(); ++it)
{
cout << (*it) << endl;
}*/
system("pause");
return 0;
}
结果:
张三
李四
王二麻子
请按任意键继续. . .
我们简单来看一下迭代器,我这里写了一段STL的迭代器代码作为对比,我们的迭代器用法与STL的基本相同。首先创建一个迭代器,初值为容器首元素位置,然后进行迭代,直到到达尾元素为止。每次迭代向后移动一个元素。
三.迭代器模式的总结
最后,我们来看一下迭代器模式的优点,缺点以及使用时机:优点:
1)迭代器简化了容器类,实现了单一职责原则。将遍历和存储功能分离,不论是新增容器类型还是新增迭代器都符合开放-封闭原则。
2)可以提供多种迭代方式,比如新增一个从后向前迭代的迭代器等。
缺点:
1)迭代器的设计比较难,很难抽象出一套比较完整的迭代器基类。
2)迭代器使系统类个数增加,一定程度上难以理解。
使用时机:
1)访问一个聚合对象的内容而无须暴露它的内部表示。将聚合对象的访问与内部数据的存储分离,使得访问聚合对象时无须了解其内部实现细节。
2) 需要为一个聚合对象提供多种遍历方式。
3) 为遍历不同的聚合结构提供一个统一的接口,在该接口的实现类中为不同的聚合结构提供不同的遍历方式,而客户端可以一致性地操作该接口。
最后,顺带提一句,迭代器模式太有用了,以至于语言或者基础库都提供了完整的迭代器实现,反倒这个模式我们自己实现的意义不大了....
相关文章推荐
- 设计模式学习笔记——迭代器模式
- 【学习笔记javascript设计模式与开发实践(迭代器模式)----7】
- 设计模式学习笔记-迭代器模式 一般
- 设计模式学习笔记--迭代器模式
- java学习笔记-设计模式17(迭代器模式)
- 设计模式C++学习笔记之十四(Iterator迭代器模式)
- 设计模式学习笔记---迭代器模式iterator pattern(Java版)
- 步步为营 .NET 设计模式学习笔记 十一、Iterator(迭代器模式)
- 设计模式学习笔记——迭代器模式
- 《Head First 设计模式》学习笔记:迭代器模式与组合模式
- 【HeadFirst 设计模式学习笔记】9 迭代器模式
- 设计模式学习笔记——迭代器模式
- 设计模式学习笔记之迭代器模式
- 步步为营 .NET 设计模式学习笔记 十一、Iterator(迭代器模式)
- 设计模式学习笔记之迭代器模式
- 【设计模式学习笔记十七】【行为模式】【迭代器模式(Interpreter)】
- 设计模式学习笔记--迭代器模式
- 【设计模式】学习笔记12:迭代器模式(Iterator)
- HeadFirst 设计模式学习笔记9--迭代器模式
- 设计模式C++学习笔记之三(Iterator迭代器模式)