一、引言

  在上篇博文中分享了我对命令模式的理解,命令模式主要是把行为进行抽象成命令,使得请求者的行为和接受者的行为形成低耦合。在这一章中,将介绍一下迭代器模式。

  二、迭代器模式的介绍

  迭代器是针对集合对象而生的。对于集合对象而言,必然涉及到集合元素的添加删除操作,同时也肯定支持遍历集合元素的操作。我们此时可以把遍历操作也放在集合对象中,但这样的话,集合对象就承担太多的责任了。面向对象设计原则中有一条是单一职责原则,所以我们要尽可能地分离这些职责,用不同的类去承担不同的职责。迭代器模式就是用迭代器类来承担遍历集合元素的职责。

  2.1 迭代器模式的定义

  迭代器模式提供了一种方法顺序访问一个聚合对象(理解为集合对象)中各个元素,而又无需暴露该对象的内部表示,这样既可以做到不暴露集合的内部结构,又可让外部代码透明地访问集合内部的数据。

  2.2 迭代器模式的结构

  既然,迭代器模式承担了遍历集合对象的职责,那该模式自然存在2个类:一个是聚合类,一个是迭代器类。在面向对象设计原则中还有一条是针对接口编程。所以,在迭代器模式中,抽象了2个接口:一个是聚合接口,另一个是迭代器接口,这样迭代器模式中就四个角色了,具体的类图如下所示:

  
  从上图可以看出,迭代器模式由以下角色组成:

  1)迭代器角色(Iterator):迭代器角色负责定义访问和遍历元素的接口。

  2)具体迭代器角色(Concrete Iteraror):具体迭代器角色实现了迭代器接口,并需要记录遍历中的当前位置。

  3)聚合角色(Aggregate):聚合角色负责定义获得迭代器角色的接口。

  4)具体聚合角色(Concrete Aggregate):具体聚合角色实现聚合角色接口。

  2.3 迭代器模式的实现

  介绍完迭代器模式之后,下面就具体看看迭代器模式的实现,具体实现代码如下:

  // 抽象聚合类
public interface IListCollection
{
Iterator GetIterator();
} // 迭代器抽象类
public interface Iterator
{
bool MoveNext();
Object GetCurrent();
void Next();
void Reset();
} // 具体聚合类
public class ConcreteList : IListCollection
{
int[] collection;
public ConcreteList()
{
collection = new int[] { , , , };
} public Iterator GetIterator()
{
return new ConcreteIterator(this);
} public int Length
{
get { return collection.Length; }
} public int GetElement(int index)
{
return collection[index];
}
} // 具体迭代器类
public class ConcreteIterator : Iterator
{
// 迭代器要集合对象进行遍历操作,自然就需要引用集合对象
private ConcreteList _list;
private int _index; public ConcreteIterator(ConcreteList list)
{
_list = list;
_index = ;
} public bool MoveNext()
{
if (_index < _list.Length)
{
return true;
}
return false;
} public Object GetCurrent()
{
return _list.GetElement(_index);
} public void Reset()
{
_index = ;
} public void Next()
{
if (_index < _list.Length)
{
_index++;
} }
} // 客户端
class Program
{
static void Main(string[] args)
{
Iterator iterator;
IListCollection list = new ConcreteList();
iterator = list.GetIterator(); while (iterator.MoveNext())
{
int i = (int)iterator.GetCurrent();
Console.WriteLine(i.ToString());
iterator.Next();
} Console.Read();
}
}

  自然,上面代码的运行结果也是对集合每个元素的输出,具体运行结果如下图所示:

  三、.NET中迭代器模式的应用

  在.NET下,迭代器模式中的聚集接口和迭代器接口都已经存在了,其中IEnumerator接口扮演的就是迭代器角色,IEnumberable接口则扮演的就是抽象聚集的角色。只有一个GetEnumerator()方法,关于这两个接口的定义可以自行参考MSDN。在.NET 1.0中,.NET 类库中很多集合都已经实现了迭代器模式,大家可以用反编译工具Reflector来查看下mscorlib程序集下的System.Collections命名空间下的类。这里给出ArrayList的定义代码,具体实现代码可以自行用反编译工具查看,具体代码如下所示:

public class ArrayList : IList, ICollection, IEnumerable, ICloneable
{
// Fields
private const int _defaultCapacity = ;
private object[] _items;
private int _size;
[NonSerialized]
private object _syncRoot;
private int _version;
private static readonly object[] emptyArray; public virtual IEnumerator GetEnumerator();
public virtual IEnumerator GetEnumerator(int index, int count); // Properties
public virtual int Capacity { get; set; }
public virtual int Count { get; }
..............// 更多代码请自行用反编译工具Reflector查看
}

  通过查看源码你可以发现,ArrayList中迭代器的实现与我们前面给出的示例代码非常相似。然而,在.NET 2.0中,由于有了yield return关键字,实现迭代器模式就更简单了。

  四、迭代器模式的适用场景

  在下面的情况下可以考虑使用迭代器模式:

  1)系统需要访问一个聚合对象的内容而无需暴露它的内部表示。

  2)系统需要支持对聚合对象的多种遍历。

  3)系统需要为不同的聚合结构提供一个统一的接口。

  五、迭代器模式的优缺点

  由于迭代器承担了遍历集合的职责,从而有以下的优点:

  1)迭代器模式使得访问一个聚合对象的内容而无需暴露它的内部表示,即迭代抽象。

  2)迭代器模式为遍历不同的集合结构提供了一个统一的接口,从而支持同样的算法在不同的集合结构上进行操作。

  迭代器模式存在的缺陷:

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

  六、总结

  到这里,本博文的内容就介绍结束了。迭代器模式就是抽象一个迭代器类来分离了集合对象的遍历行为,这样既可以做到不暴露集合的内部结构,又可让外部代码透明地访问集合内部的数据。

参考链接:http://www.cnblogs.com/zhili/p/IteratorPattern.html

【17】迭代器模式(Iterator Pattern)的更多相关文章

  1. 设计模式(十):从电影院中认识"迭代器模式"(Iterator Pattern)

    上篇博客我们从醋溜土豆丝与清炒苦瓜中认识了“模板方法模式”,那么在今天这篇博客中我们要从电影院中来认识"迭代器模式"(Iterator Pattern).“迭代器模式”顾名思义就是 ...

  2. 乐在其中设计模式(C#) - 迭代器模式(Iterator Pattern)

    原文:乐在其中设计模式(C#) - 迭代器模式(Iterator Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 迭代器模式(Iterator Pattern) 作者:weba ...

  3. 设计模式学习--迭代器模式(Iterator Pattern)和组合模式(Composite Pattern)

    设计模式学习--迭代器模式(Iterator Pattern) 概述 ——————————————————————————————————————————————————— 迭代器模式提供一种方法顺序 ...

  4. 二十四种设计模式:迭代器模式(Iterator Pattern)

    迭代器模式(Iterator Pattern) 介绍提供一种方法顺序访问一个聚合对象中各个元素,而又不需暴露该对象的内部表示. 示例有一个Message实体类,某聚合对象内的各个元素均为该实体对象,现 ...

  5. 设计模式 - 迭代器模式(iterator pattern) 具体解释

    迭代器模式(iterator pattern) 详细解释 本文地址: http://blog.csdn.net/caroline_wendy 迭代器模式(iterator pattern) : 提供一 ...

  6. 设计模式系列之迭代器模式(Iterator Pattern)——遍历聚合对象中的元素

    模式概述 模式定义 模式结构图 模式伪代码 模式改进 模式应用 模式在JDK中的应用 模式在开源项目中的应用 模式总结 说明:设计模式系列文章是读刘伟所著<设计模式的艺术之道(软件开发人员内功修 ...

  7. 迭代器模式(Iterator Pattern)

    迭代器模式定义:Iterator Pattern提供一种方法顺序访问一个聚合元素中的各个元素,而又不暴漏内部方法 酒吧提供beer和wine: public class Bar { private L ...

  8. 16.迭代器模式(Iterator Pattern)

    using System; namespace ConsoleApplication9 { class Program { /// <summary> /// 迭代器模式提供了一种方法顺序 ...

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

    一.概述在软件开发过程中,我们可能会希望在不暴露一个集合对象内部结构的同时,可以让外部代码透明地访问其中包含的元素.迭代器模式可以解决这一问题.二.迭代器模式迭代器模式提供一种方法顺序访问一个集合对象 ...

  10. [设计模式] 16 迭代器模式 Iterator Pattern

    在GOF的<设计模式:可复用面向对象软件的基础>一书中对迭代器模式是这样说的:提供一种方法顺序访问一个聚合对象中各个元素,而又不需要暴露该对象的内部表示. 类图和实例: 迭代器模式由以下角 ...

随机推荐

  1. OSLab文件描述符

      日期:2019/3/24 内容:Linux文件描述符.   一.基本概念 文件描述符(File Descriptor) 一个非负整数.应用程序利用文件描述符来访问文件.打开现存文件或新建文件时,内 ...

  2. 简单题(K-D Tree)

    简单题不简单-- 我们把单点加操作改成插入一个权值为增加量的点,将问题转化成询问一个矩阵中所有点的和,用 \(K-D\ Tree\) 维护,时间复杂度 \(O(n\sqrt{n})\) \(Code\ ...

  3. Linux - 针对用户账号的常用操作

    用户目录 除root用户外,其他默认的用户目录一般为/home/<user name>. 可以通过如下步骤修改默认用户目录 修改/etc/passwd文件中相应用户的路径信息 停止此用户的 ...

  4. springbootf访问静态文件资源

    springboot目录结构: 网友说在springboot的配置文件中加 现在访问static目录下的jquery文件 用jquery在页面做一个弹窗 启动服务看页面效果 页面没有出现弹窗 ,连jq ...

  5. 【sping揭秘】9、容器内部事件发布(二)

    写在前面---------------------------------- 命运多舛,痴迷淡然 不知下一步该往哪里走,现在应该是我的迷茫期... 加油,快点走出去!!! 聪明的网友们,你们有没有迷茫 ...

  6. 【liferay】6、关于liferay中使用requestMapping映射地址提交表单

    1.接着上一篇博客,从新在定义一下页面 <%@ page contentType="text/html; charset=utf-8" language="java ...

  7. odoo开发笔记:Server+Action服务器动作自动触发执行

           Odoo的市场定位是SME(中小型企业),这个市场的ERP产品,多如牛毛,产品各具特色.不过,Odoo的自动化处理机制,可以睥睨天下,无人能及.包括一些大型国产软件,如用友.金蝶也不具备 ...

  8. ABP集成WIF实现单点登录

    ABP集成WIF实现单点登录 参考 ojlovecd写了三篇关于WIF文章. 使用WIF实现单点登录Part III —— 正式实战 使用WIF的一些开源示例. https://github.com/ ...

  9. 自测 基础 js 脚本。

    <html> <head> <script> //function(<text>a{[]}lert('x')</text>)() docum ...

  10. CentOS 6.7 下 MYSQL 5.7 的安装与配置

    安装 #yum源 http://dev.mysql.com/downloads/repo/yum/ #安装 rpm -Uvh http://dev.mysql.com/get/mysql57-comm ...