一:概念

迭代模式是行为模式之一,它把对容器中包含的内部对象的访问委让给外部类,使用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. python之旅5【第五篇】

    装饰器详解 函数刚开始不解析内部,只是放进内存 装饰器是函数,只不过该函数可以具有特殊的含义,装饰器用来装饰函数或类,使用装饰器可以在函数执行前和执行后添加相应操作. 1 下面以一个函数开始,理解下面 ...

  2. POJ 3621-Sightseeing Cows-最优比率环|SPFA+二分

    最优比率环问题.二分答案,对于每一个mid,把节点的happy值归类到边上. 对于每条边,用mid×weight减去happy值,如果不存在负环,说明还可以更大. /*---------------- ...

  3. npm、webpack、vue-cli

    Node.js   npm 什么是Node.js  以及npm 简单的来说 Node.js 就是运行在服务端的JavaScript,基于Chrome V8 引擎的. npm 是Node.js 的包管理 ...

  4. Codeforces1065F Up and Down the Tree 【树形DP】

    推荐一道联赛练习题. 题目分析: 你考虑进入一个子树就可能上不来了,如果上得来的话就把能上来的全捡完然后走一个上不来的,所以这就是个基本的DP套路. 代码: #include<bits/stdc ...

  5. HDU4035 Maze 【树形DP】【期望DP】

    题目分析: 以前一直不会这个方法, 我好菜啊. 转移分为三个部分,一个是直接成功,一个是转移到E1,还有一个是转移到自己周围的一圈儿点. 如果是叶子那么只能转移到父亲,如果不是叶子可以把非叶子的转移代 ...

  6. Django+Vue打造购物网站(一)

    环境搭建 python == 3.6 Django == 2.0 创建工程 django-admin startproject MxShop 配置setting.py文件 # 数据库 DATABASE ...

  7. Java 强制类型转换(类转换注意事项)

    将一个类型强制转换成另一个类型的过程被称为类型转换.例如: double x =3.14; int y = (int)x; 将表达式x的值转换成整数类型,舍弃小数部分. 有时候也可能是类的对象引用的转 ...

  8. CANOE入门(二)

    CAPL就是Communication Application Programming Laguage的缩写,CAPL类似于C语言的语法,因此所有的语法请参考C语言教程,这里不在这里进行详述,关于C语 ...

  9. FZU - 1901 Period II(kmp所有循环节)

    Problem Description For each prefix with length P of a given string S,if S[i]=S[i+P] for i in [0..SI ...

  10. 51nod1079 poj2891 中国剩余定理与其扩展

    题目链接:http://www.51nod.com/Challenge/Problem.html#!#problemId=1079 一个正整数K,给出K Mod 一些质数的结果,求符合条件的最小的K. ...