一、动机(Motivate)

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

二、意图(Intent)

提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露该对象的内部表示。                                 ——《设计模式》GoF

三、结构图


四、模式的组成

从迭代器模式的结构图可以看出,它涉及到四个角色,它们分别是:
(1)、抽象迭代器(Iterator):抽象迭代器定义了访问和遍历元素的接口,一般声明如下方法:用于获取第一个元素的first(),用于访问下一个元素的next(),用于判断是否还有下一个元素的hasNext(),用于获取当前元素的currentItem(),在其子类中将实现这些方法。
(2)、具体迭代器(ConcreteIterator):具体迭代器实现了抽象迭代器接口,完成对集合对象的遍历,同时在对聚合进行遍历时跟踪其当前位置。
(3)、抽象聚合类(Aggregate):抽象聚合类用于存储对象,并定义创建相应迭代器对象的接口,声明一个createIterator()方法用于创建一个迭代器对象。
(4)、具体聚合类(ConcreteAggregate):具体聚合类实现了创建相应迭代器的接口,实现了在抽象聚合类中声明的createIterator()方法,并返回一个与该具体聚合相对应的具体迭代器ConcreteIterator实例。

五、迭代器模式的代码实现

迭代器模式在现实生活中也有类似的例子,比如:在部队中,我们可以让某一队伍当中的某人出列,或者让队列里面的每个人依次报名,其实这个过程就是一个遍历的过程。

// 客户端(Client)
static void Main(string[] args)
{
Iterator iterator;
ITroopQueue list = new ConcreteTroopQueue();
iterator = list.GetIterator(); while (iterator.MoveNext())
{
string ren = (string)iterator.GetCurrent();
Console.WriteLine(ren);
iterator.Next();
} Console.Read();
} // 部队队列的抽象聚合类--该类型相当于抽象聚合类Aggregate
public interface ITroopQueue
{
Iterator GetIterator();
} // 迭代器抽象类
public interface Iterator
{
bool MoveNext();
Object GetCurrent();
void Next();
void Reset();
} //部队队列具体聚合类--相当于具体聚合类ConcreteAggregate
public sealed class ConcreteTroopQueue : ITroopQueue
{
private string[] collection; public ConcreteTroopQueue()
{
collection = new string[] { "黄飞鸿", "方世玉", "洪熙官", "严咏春" };
} public Iterator GetIterator()
{
return new ConcreteIterator(this);
} public int Length
{
get { return collection.Length; }
} public string GetElement(int index)
{
return collection[index];
}
} // 具体迭代器类
public sealed class ConcreteIterator : Iterator
{
// 迭代器要集合对象进行遍历操作,自然就需要引用集合对象
private ConcreteTroopQueue _list;
private int _index; public ConcreteIterator(ConcreteTroopQueue list)
{
_list = list;
_index = 0;
} public bool MoveNext()
{
if (_index < _list.Length)
{
return true;
}
return false;
} public Object GetCurrent()
{
return _list.GetElement(_index);
} public void Reset()
{
_index = 0;
} public void Next()
{
if (_index < _list.Length)
{
_index++;
} }
}

六、迭代器模式的实现要点:

1、迭代抽象:访问一个聚合对象的内容而无需暴露它的内部表示。
     2、迭代多态:为遍历不同的集合结构提供一个统一的接口,从而支持同样的算法在不同的集合结构上进行操作。
     3、迭代器的健壮性考虑:遍历的同时更改迭代器所在的集合结构,会导致问题。

迭代器模式的优点:

(1)、迭代器模式使得访问一个聚合对象的内容而无需暴露它的内部表示,即迭代抽象。
          (2)、迭代器模式为遍历不同的集合结构提供了一个统一的接口,从而支持同样的算法在不同的集合结构上进行操作

迭代器模式的缺点:

(1)、迭代器模式在遍历的同时更改迭代器所在的集合结构会导致出现异常。所以使用foreach语句只能在对集合进行遍历,不能在遍历的同时更改集合中的元素。

迭代器模式的使用场景:

(1)、访问一个聚合对象的内容而无需暴露它的内部表示。
       (2)、支持对聚合对象的多种遍历。
       (3)、为遍历不同的聚合结构提供一个统一的接口(即, 支持多态迭代)。

七、.NET 中迭代器模式的实现

在mscorlib程序集里有这样一个命名空间,该命名空间就是:System.Collections,在该命名空间里面早已有了迭代器模式的实现。对于聚集接口和迭代器接口已经存在了,其中IEnumerator扮演的就是迭代器的角色,它的实现如下:

public interface IEnumerator
{
object Current
{
get;
} bool MoveNext(); void Reset();
}

属性Current返回当前集合中的元素,Reset()方法恢复初始化指向的位置,MoveNext()方法返回值true表示迭代器成功前进到集合中的下一个元素,返回值false表示已经位于集合的末尾。能够提供元素遍历的集合对象,在.Net中都实现了IEnumerator接口。
IEnumerable则扮演的就是抽象聚集的角色,只有一个GetEnumerator()方法,如果集合对象需要具备跌代遍历的功能,就必须实现该接口。

public interface IEnumerable
{
IEumerator GetEnumerator();
}

抽象聚合角色(Aggregate)和抽象迭代器角色(Iterator)分别是IEnumerable接口和IEnumerator接口,具体聚合角色(ConcreteAggregate)有Queue类型, BitArray等类型,

行为型模式(三) 迭代器模式(Iterator)的更多相关文章

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

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

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

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

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

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

  4. 行为型设计模式之迭代器模式(Iterator)

    结构 意图 提供一种方法顺序访问一个聚合对象中各个元素, 而又不需暴露该对象的内部表示. 适用性 访问一个聚合对象的内容而无需暴露它的内部表示. 支持对聚合对象的多种遍历. 为遍历不同的聚合结构提供一 ...

  5. [19/04/29-星期一] GOF23_行为型模式(责任链模式、迭代器模式)

    一.行为模式 二.责任链模式(chainOfResponsibility) [一个请求类] /*** 请假类 * 封装请假的基本信息 */ package cn.sxt.chainOfResponsi ...

  6. 设计模式---数据结构模式之迭代器模式(Iterate)

    一:概念 迭代模式是行为模式之一,它把对容器中包含的内部对象的访问委让给外部类,使用Iterator(遍历)按顺序进行遍历访问的设计模式. 在应用Iterator模式之前,首先应该明白Iterator ...

  7. JavaScript---设计模式之迭代器模式

    迭代器模式提供一种方法顺序访问一个聚合对象中各个元素,而又不需要暴露该方法中的内部表示. jQuery中我们经常会用到一个each函数就是迭代器模式 作用 为遍历不同的集合结构提供一个统一的接口,从而 ...

  8. 《Javascript设计模式与开发实践》关于设计模式典型代码的整理:单例模式、策略模式、代理模式、迭代器模式、发布-订阅模式、命令模式、组合模式

    1.单例模式:保证一个类仅有一个实例,并提供一个访问它的全局访问点. 使用闭包封装私有变量// 使用闭包创建单例var user = (function () { var _name = 'sven' ...

  9. GoF23种设计模式之行为型模式之迭代器模式

    一.概述    给定一种语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子.二.适用性1.当访问一个聚合对象的内容而无需暴露它的内部表示的时候.2.当对聚合对象的多 ...

随机推荐

  1. Linux下创建Oracle19C的数据库实例

    接上一篇博客,安装 Oracle19chttps://www.cnblogs.com/xuzhaoyang/p/11264557.html 切换到root用户下,切换目录到db_1,执行,遇到选择路径 ...

  2. C++—多态与继承

    一.基本概念 1.类的继承,是新的类从已有类那里得到已有的特性.或从已有类产生新类的过程就是类的派生.原有的类称为基类或父类,产生的新类称为派生类或子类. 2.派生类的声明: class 派生类名:继 ...

  3. java笔记——java加载与执行

    java的加载与执行过程: 编译阶段: 首先,我们先创建一个java源文件xxx.java 2. 经过javac.exe编译(如果源文件没有语法错误),生成一个或多个.class文件,注意的是此时的字 ...

  4. Python-13-模块和包

    一.模块的概念 在计算机程序的开发过程中,随着程序代码越写越多,在一个文件里代码就会越来越长,越来越不容易维护. 为了编写可维护的代码,我们把很多函数分组,分别放到不同的文件里,这样,每个文件包含的代 ...

  5. SAS学习笔记57 template的管理

    template查询 首先点击SAS Windows左上方查询框,输入“odst”或者“odstemplates”,如下所示: 然后点击enter键,进入查询的template文件夹,如下所示: 这里 ...

  6. AS3事件类型

    Event事件类型: ACTIVATE       激活事件 DEACTIVATE 对象休眠事件 ADDED      可视对象添加事件 ADDED_TO_STAGE 可视对象添加到舞台事件 REMO ...

  7. git 学习笔记 ---远程仓库

    Git是分布式版本控制系统,同一个Git仓库,可以分布到不同的机器上.怎么分布呢?最早,肯定只有一台机器有一个原始版本库,此后,别的机器可以“克隆”这个原始版本库,而且每台机器的版本库其实都是一样的, ...

  8. Windows服务创建及发布

    二.创建Windows Service 1.新建一个Windows Service,并将项目名称改为“MyWindowsService”,如下图所示: 2.在解决方案资源管理器内将Service1.c ...

  9. 阿里云ECS服务器将默认的Ubuntu系统改成桌面版

    以Ubuntu14.04 64位 为例 1.用自己PC登录阿里云,停止正在运行的实例 2.重装系统 更换系统盘->选择"公共镜像".Ubuntu. Ubuntu14.04 6 ...

  10. DDL和DML 的区别

    DDL (Data Definition Language 数据定义语言) create table 创建表 alter table 修改表 drop table 删除表 truncate table ...