一:概念

迭代模式是行为模式之一,它把对容器中包含的内部对象的访问委让给外部类,使用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. 第二十天 模块 sys os os下path settings random shuit

    一.sys模块 1.sys.argv 命令行参数List,第一个元素是程序本身路径 2.sys.exit(n) 退出程序,正常退出时exit(0) 3.sys.version 获取Pythonn解释程 ...

  2. 洛谷P2045 K方格取数(算竞进阶习题)

    费用流 又是一道网络流的模型,对于这种费用与经过次数有关的边,我们经常把边拆成多条,比如这个题,第一次费用是x,第二次是0,我们就可以先把点拆成入点和出点,入点和出点又连两条边,第一条容量为1,费用为 ...

  3. 【HDU - 4345 】Permutation(DP)

    BUPT2017 wintertraining(15) #8F 题意 1到n的排列,经过几次置换(也是一个排列)回到原来的排列,就是循环了. 现在给n(<=1000),求循环周期的所有可能数. ...

  4. Logger.error方法之打印错误异常的详细堆栈信息

    一.问题场景 使用Logger.error方法时只能打印出异常类型,无法打印出详细的堆栈信息,使得定位问题变得困难和不方便. 二.先放出结论 Logger类下有多个不同的error方法,根据传入参数的 ...

  5. 【BZOJ4891】[TJOI2017]龙舟(Pollard_rho)

    [BZOJ4891][TJOI2017]龙舟(Pollard_rho) 题面 BZOJ 洛谷 题解 看了半天题....就是让你求\(\frac{b}{a}\)在模\(M\)意义下的值... 首先把\( ...

  6. <数据结构基础学习>(一)数组

    一.数组基础 1.数组,即把数据码成一排存放. 数组优点:快速查询. 数组最好应用于“索引有语意”的情况,但并非所有有语意的索引都适用于数组,数组也可以处理“索引没有语意”的情况. 2.增.删.改.查 ...

  7. 「SDOI2014」Lis 解题报告

    「SDOI2014」Lis 题目描述 给定序列 \(A\),序列中的每一项 \(A_i\) 有删除代价 \(B_i\) 和附加属性 \(C_i\). 请删除若干项,使得 \(A\) 的最长上升子序列长 ...

  8. su命令详解

    -----------------------------------------------------------------su 权限设置[root@localhost ~]# vim /etc ...

  9. 在浏览器中浏览git上项目目录结构

    效果如下,参考:https://gitee.com/oschina/GitCodeTree

  10. luogu4728 双递增序列 (dp)

    设f[i][j]表示以i位置为第一个序列的结尾,第一个序列的长度为j,第二个序列的结尾的最小值 那么对于f[i][j],有转移$f[i+1][j+1]=min\{f[i+1][j+1],f[i][j] ...