一:概念

迭代模式是行为模式之一,它把对容器中包含的内部对象的访问委让给外部类,使用Iterator(遍历)按顺序进行遍历访问的设计模式。

在应用Iterator模式之前,首先应该明白Iterator模式用来解决什么问题。或者说,如果不使用Iterator模式,会存在什么问题?

.由容器自己实现顺序遍历。直接在容器类里直接添加顺序遍历方法
.让调用者自己实现遍历。直接暴露数据细节给外部。

以上方法1与方法2都可以实现对遍历,这样有问题呢?

,容器类承担了太多功能:一方面需要提供添加删除等本身应有的功能;一方面还需要提供遍历访问功能。
,往往容器在实现遍历的过程中,需要保存遍历状态,当跟元素的添加删除等功能夹杂在一起,很容易引起混乱和程序运行错误等。
Iterator模式就是为了有效地处理按顺序进行遍历访问的一种设计模式,简单地说,Iterator模式提供一种有效的方法,可以屏蔽聚集对象集合的容器类的实现细节,而能对容器内包含的对象元素按顺序进行有效的遍历访问。

所以,Iterator模式的应用场景可以归纳为满足以下几个条件:

.访问容器中包含的内部对象;
.按顺序访问

二:动机

在软件构建过程中,集合对象内部结构常常变化各异。但对于这些集合对象,我们希望在不暴露其内部结构的同时,可以让外部客户代码透明的访问其中包含的元素;同时这种“透明遍历”也为“同一种算法在多种集合对象上进行操作”提供了可能。
使用面向对象技术将这种遍历机制抽象为“迭代器对象”为“因对变化中的集合对象”提供了一种优雅的方式。

三:模式定义

提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露(隔离变化,稳定)该对象的内部表示。

                                                                                    ——《设计模式》GoF
这种方式在C++现在来说已经过时了,因为泛型编程和STL中实现了迭代器。
迭代器模式最核心缺点就是出现在面向对象上,虚函数调用是有性能成本的,需要绕一个虚函数的表指针,然后找到函数地址,才能去调用,要经过指针间接运算。当循环次数太高后,性能就会被削减。
泛型编程中优点:迭代器是使用模板来实现的,而模板(也是一种多态技术),但是他实现的多态是编译时多态,编译器会在编译时判断具体是调用哪段代码。
虚函数是运行时多态,运行时多态性能低于编译时多态,编译时多态不需要计算他的地址了,因此STL性能高于面向对象模式迭代器,功能也更多。

四:类图(结构)

五:代码讲解

(一)Iterator基类

template<typename T>
class Iterator
{
public:
virtual void first() = ;
virtual void next() = ;
virtual bool isDone() const = ;
virtual T& current() = ;
};

(二)基类Collection返回迭代器

template<typename T>
class MyCollection{ public: Iterator<T> GetIterator(){
//...
} };

(三)子类CollectionIterator实现迭代方法

template<typename T>
class CollectionIterator : public Iterator<T>{
MyCollection<T> mc;
public: CollectionIterator(const MyCollection<T> & c): mc(c){ } void first() override { }
void next() override { }
bool isDone() const override{ }
T& current() override{ }
};

(四)进行调用

void MyAlgorithm()
{
MyCollection<int> mc; Iterator<int> iter= mc.GetIterator(); for (iter.first(); !iter.isDone(); iter.next()){
cout << iter.current() << endl;
} }

六:要点总结

(一)Java,C#类库是按照上面实现,因为毕竟没有编译时多态,现在C++基本没有这种实现,随着技术的发展,有些设计模式会过时,但是思想不会过时。

(二)迭代抽象:访问一个聚合对象的内容而无需暴露他的内部表示

(三)迭代多态:为遍历不同的集合结构提供一个统一的接口,从而支持同样的算法在不同的集合结构上进行操作。

(四)迭代器的健壮性考虑:遍历的同时更改迭代器所在的集合结构,会导致问题。

七:案例实现

(一)实现迭代器基类

class Iterator
{
public:
virtual void first() = ;
virtual void next() = ;
virtual bool isDone() const= ;
virtual int& current() = ;
virtual ~Iterator(){}
};

(二)实现聚合基类

class Aggregate
{
public:
virtual Iterator* CreateIntertor() = ;
virtual int getSize() = ;
virtual int getItem(int index) = ;
virtual ~Aggregate(){}
};

(三)实现具体迭代器子类

class ConcreteIterator :public Iterator
{
private:
Aggregate* _ag;
int _idx;
public:
ConcreteIterator(Aggregate* ag)
{
_ag = ag;
_idx = ;
} virtual void first()
{
_idx = ;
} virtual void next()
{
if (_idx<_ag->getSize())
_idx++;
} virtual bool isDone() const
{
return _idx == _ag->getSize();
} virtual int current()
{
return _ag->getItem(_idx);
}
};

(四)实现聚合子类

class ConcreteAggregate :public Aggregate
{
private:
int *Object;
int size;
public:
ConcreteAggregate(int size)
{
Object = (int *)malloc(size*sizeof(int)); for (int i = ; i < size; i++)
Object[i] = i*i; this->size = size;
} virtual Iterator* CreateIntertor()
{
return new ConcreteIterator(this);
} virtual int getSize()
{
return this->size;
} virtual int getItem(int index)
{
return this->Object[index];
} ~ConcreteAggregate()
{
delete Object;
}
};

(五)结果测试

int main()
{
Aggregate* ag = new ConcreteAggregate();
Iterator* it = ag->CreateIntertor(); for (it; !it->isDone(); it->next())
cout << it->current() << endl; delete it;
delete ag; system("pause");
return ;
}

作为迭代器,最好设置为模板类吧
#include <iostream>
#include <string> using namespace std; template<typename T>
class Iterator
{
public:
virtual void first() = ;
virtual void next() = ;
virtual bool isDone() const= ;
virtual T& current() = ;
virtual ~Iterator(){}
}; template<typename T>
class Aggregate
{
public:
virtual Iterator<T>* CreateIntertor() = ;
virtual int getSize() = ;
virtual T& getItem(int index) = ;
virtual ~Aggregate(){}
}; template<typename T>
class ConcreteIterator :public Iterator<T>
{
private:
Aggregate<T>* _ag;
int _idx;
public:
ConcreteIterator(Aggregate<T>* ag)
{
_ag = ag;
_idx = ;
} virtual void first()
{
_idx = ;
} virtual void next()
{
if (_idx<_ag->getSize())
_idx++;
} virtual bool isDone() const
{
return _idx == _ag->getSize();
} virtual T& current()
{
return _ag->getItem(_idx);
}
}; template<typename T>
class ConcreteAggregate :public Aggregate<T>
{
private:
T *Object;
int size;
public:
ConcreteAggregate(int size)
{
Object = (T *)malloc(size*sizeof(T)); for (int i = ; i < size; i++)
Object[i] = +i; this->size = size;
} virtual Iterator<T>* CreateIntertor()
{
return new ConcreteIterator<T>(this);
} virtual int getSize()
{
return this->size;
} virtual T& getItem(int index)
{
return this->Object[index];
} ~ConcreteAggregate()
{
delete Object;
}
}; int main()
{
Aggregate<char>* ag = new ConcreteAggregate<char>();
Iterator<char>* it = ag->CreateIntertor(); for (it; !it->isDone(); it->next())
cout << it->current() << endl; delete it;
delete ag; system("pause");
return ;
}

使用模板函数实现(重点)

设计模式---数据结构模式之迭代器模式(Iterate)的更多相关文章

  1. Javascript设计模式之我见:迭代器模式

    大家好!本文介绍迭代器模式及其在Javascript中的应用. 模式介绍 定义 提供一种方法顺序一个聚合对象中各个元素,而又不暴露该对象内部表示. 类图及说明 Iterator抽象迭代器 抽象迭代器负 ...

  2. Java进阶篇设计模式之九----- 解释器模式和迭代器模式

    前言 在上一篇中我们学习了行为型模式的责任链模式(Chain of Responsibility Pattern)和命令模式(Command Pattern).本篇则来学习下行为型模式的两个模式, 解 ...

  3. Java设计模式之九 ----- 解释器模式和迭代器模式

    前言 在上一篇中我们学习了行为型模式的责任链模式(Chain of Responsibility Pattern)和命令模式(Command Pattern).本篇则来学习下行为型模式的两个模式, 解 ...

  4. Python使用设计模式中的责任链模式与迭代器模式的示例

    Python使用设计模式中的责任链模式与迭代器模式的示例 这篇文章主要介绍了Python使用设计模式中的责任链模式与迭代器模式的示例,责任链模式与迭代器模式都可以被看作为行为型的设计模式,需要的朋友可 ...

  5. 《Head first设计模式》学习笔记 – 迭代器模式

    <Head first设计模式>学习笔记 – 迭代器模式 代器模式提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的表示. 爆炸性新闻:对象村餐厅和对象村煎饼屋合并了!真是个 ...

  6. 设计模式(十七)——迭代器模式(ArrayList 集合应用源码分析)

    1 看一个具体的需求 编写程序展示一个学校院系结构:需求是这样,要在一个页面中展示出学校的院系组成,一个学校有多个学院, 一个学院有多个系.如图: 2 传统的设计方案(类图) 3 传统的方式的问题分析 ...

  7. C#设计模式之十六迭代器模式(Iterator Pattern)【行为型】

    一.引言   今天我们开始讲"行为型"设计模式的第三个模式,该模式是[迭代器模式],英文名称是:Iterator Pattern.还是老套路,先从名字上来看看."迭代器模 ...

  8. C#设计模式之十五迭代器模式(Iterator Pattern)【行为型】

    一.引言 今天我们开始讲“行为型”设计模式的第三个模式,该模式是[迭代器模式],英文名称是:Iterator Pattern.还是老套路,先从名字上来看看.“迭代器模式”我第一次看到这个名称,我的理解 ...

  9. C#设计模式(15)——迭代器模式

    1.迭代器模式介绍 迭代器模式主要用于遍历聚合对象,将聚合对象的遍历行为分离出来,抽象为一个迭代器来负责.迭代器模式用的十分普遍,C#/JAVA等高级语言都对迭代器进行了封装用于遍历数组,集合,列表等 ...

随机推荐

  1. Android Studio 显示 logcat

    首先调出 logcat,在整个android studio的左下角(藏的好,尼玛.) 接着设置下面三个红框 1 选择你自己的模拟器. 2 选择Warm 3 选择not filter

  2. 进入Docker容器的4种方式

    进入Docker容器的4种方式 在使用Docker创建了容器之后,大家比较关心的就是如何进入该容器了,其实进入Docker容器有好几多种方式,这里我们就讲一下常用的几种进入Docker容器的方法. 进 ...

  3. java JUC

    https://www.cnblogs.com/q151860/p/8589683.html

  4. 使用IDEA部署项目到远程服务器

    1.选择Tools -> Deployment -> Configuration... 2.配置连接信息,Linux服务器一般都选择SFTP 3.配置本地上传文件路径.远程上传文件路径 4 ...

  5. linux tar 解压命令

    如果提示 common not find 先进行安装如下 wget http://www.rarsoft.com/rar/rarlinux-5.3.0.tar.gz tar -zxvf rarlinu ...

  6. MT【307】周期数列

    (2017浙江省数学竞赛) 设数列$\{a_n\}$满足:$|a_{n+1}-2a_n|=2,|a_n|\le2,n\in N^+$证明:如果$a_1$为有理数,则从某项后$\{a_n\}$为周期数列 ...

  7. MT【263】待定系数

    已知$a,b>0$且$ab(a+b)=4$,求$2a+b$的最小值_____ 解答:$\sqrt{3}(2a+b)\ge(\sqrt{3}+1)a+b+(\sqrt{3}-1)(a+b)\ge3 ...

  8. 【luogu3733】【HAOI2017】 八纵八横 (线段树分治+线性基)

    Descroption 原题链接 给你一个\(n\)个点的图,有重边有自环保证连通,最开始有\(m\)条固定的边,要求你支持加边删边改边(均不涉及最初的\(m\)条边),每一次操作都求出图中经过\(1 ...

  9. BZOJ4695 最假女选手(势能线段树)

    BZOJ题目传送门 终于体会到初步掌握势能分析思想的重要性了. 一开始看题,感觉套路还是很一般啊qwq.直接在线段树上维护最大值和最小值,每次递归更新的时候,如果不能完全覆盖就暴力递归下去.挺好写的欸 ...

  10. Tomcat如何发布web项目

    tomcat/webapps目录是用来存放Java项目的.每一个文件夹都是一个项目,默认这个目录下已经有了四个项目,都是tomcat自带的. 其中ROOT就是我们测试Tomcat时访问的Tomcat的 ...