设计模式之迭代器

迭代器模式介绍

集合的结构

迭代器模式是一种行为设计模式,让你能在不暴露集合底层表现形式(列表、栈、树等)的情况下遍历集合中所有的元素。

迭代器模式满足了单一职责和开闭原则,外界的调用方也不需要知道任何一个不同的数据结构在使用上的遍历差异。

迭代器模式的主要思想是将集合的遍历行为抽取为单独的迭代器对象。

除实现自身算法外,迭代器还封装了遍历操作的所有细节,比如当前位置和末尾剩余元素的数量、同时还有提供一个获取集合元素的基本方法。客户端可不断调用该方法直到它不返回任何内容(已遍历所有元素)、所有迭代器必须实现相同的接口(只要有合适的迭代器,客户端代码就能兼容任何类型的集合或遍历算法)。

迭代器的结构

  • 迭代器接口:声明了遍历集合所需的操作。(获取下一个元素,获取当前位置和重新开始迭代等)

  • 具体迭代者:实现遍历集合的一种特定算法。(迭代器必须跟踪自身遍历的进度)

  • 集合接口:声明一个或多个方法来获取与集合兼容的迭代器。(返回方法的类型必须被声明为迭代器接口,因此具体集合可以返回各种不同种类的迭代器)

  • 具体集合:会在客户端请求迭代器时返回一个特定的具体迭代器类。

  • 客户端:通过集合和迭代器的接口与两者进行交互。这样一来客户端无需与具体类进行耦合,允许同一客户端代码使用各种不同的集合和迭代器。

应用场景

  • 当集合背后为复杂的数据结构,且你希望对客户端隐藏其复杂性时。

  • 想避免程序中重复的遍历代码

  • 程序代码能够遍历不同的甚至是无法预知的数据结构时。

实现方式

1、声明迭代器接口

2、声明集合接口并描述一个获取迭代器的方法,其返回值必须是迭代器接口。

3、为希望使用迭代器遍历的集合实现具体的迭代器类。

4、在你的集合类中实现集合接口。

5、在客户端使用迭代器替代所有集合遍历代码。

Demo

在迭代器的帮助下,客户端可以用一个迭代器接口以相似的方式遍历不同集合中的元素。

迭代器模式的辨别

  • 迭代器可以通过导航方法(next和previous)来轻松识别。

  • 使用迭代器的客户端代码可能没有其所遍历的集合的直接访问权限(二者是完全分离的)。


下面罗列了一个对人员集合进行排序的迭代器模式。

人员迭代器

    /// <summary>/// 人员迭代器/// 继承接口IEnumerator,显示实现了Current、MoveNext、Reset方法。/// </summary>abstract class PeopleIterator:IEnumerator  {        public abstract int Key();public abstract object Current();public abstract bool MoveNext();  public abstract void Reset();object IEnumerator.Current{get { return Current(); }}}

抽象集合迭代器和其实现

    /// <summary>/// 抽象的集合迭代器/// </summary>public abstract class AggregateIterator :IEnumerable{/// <summary>/// 得到内部的集合/// </summary>/// <returns></returns>public abstract IEnumerator GetEnumerator();}/// <summary>/// 集合的迭代器类/// 具体排序的逻辑在这里写着/// </summary>class AlphabeticalOrderIterator : PeopleIterator{private PeopleCollection _collection;private int _position = -1;private bool _reverse = false;public AlphabeticalOrderIterator(PeopleCollection collection,bool reverse=false){this._collection = collection;_reverse = reverse;if (reverse){_position = collection.getItems().Count;}            }/// <summary>/// 当前的值/// </summary>/// <returns></returns>public override object Current(){return this._collection.getItems()[_position];           }/// <summary>/// 此时的索引/// </summary>/// <returns></returns>public override int Key(){return this._position;}/// <summary>/// 下一个  位置position进行调整/// </summary>/// <returns></returns>public override bool MoveNext(){int updatedPosition = this._position + (this._reverse ? -1 : 1);if (updatedPosition >= 0 && updatedPosition < this._collection.getItems().Count){this._position = updatedPosition;return true;}else{return false;}}/// <summary>/// 重置/// </summary>public override void Reset(){this._position = this._reverse ? this._collection.getItems().Count - 1 : 0;}}

具体的人员集合和其Main()方法验证

    /// <summary>/// 具体的人员集合/// </summary>public class PeopleCollection :AggregateIterator{List<string> _collection = new List<string>();bool _direction = false;public void ReverseDirection() {_direction = !_direction;}public List<string> getItems() {return _collection;}public void AddItem(string item) {_collection.Add(item);}public override IEnumerator GetEnumerator(){return new AlphabeticalOrderIterator(this,_direction);}}class Program{static void Main(string[] args){var collection = new PeopleCollection();collection.AddItem("阿五");collection.AddItem("阿六");collection.AddItem("阿七");Console.WriteLine("遍历下");foreach (var item in collection){Console.WriteLine(item);}Console.WriteLine("倒序");collection.ReverseDirection();foreach (var item in collection){Console.WriteLine(item);}Console.ReadKey();}}
输出结果

迭代器模式在理解上还是有一点难度的,因为平时在使用集合时各个语言都已经将集合的各种操作方法都已经罗列出来了,调用人员直观调用即可。所以我们在了解其设计模式思想时,还是要多进行实践和思考。

有些东西看的多了,做的多了,自然而然就明白了。

小寄语

人生短暂,我不想去追求自己看不见的,我只想抓住我能看的见的。

原创不易,给个关注。

我是阿辉,感谢您的阅读,如果对你有帮助,麻烦关注、点赞、转发 谢谢。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/299548.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

倒啤酒竟能拿到诺贝尔物理学大奖!明明是普通操作,凭什么这么强?

全世界只有3.14 % 的人关注了青少年数学之旅倒啤酒&#xff0c;是艺术&#xff0c;更是一门学问。每个初来社会报道的男孩&#xff0c;都必须掌握这个酷炫技能。它是从古自今的文化传承&#xff0c;也是一个男人成熟的标志。向快手老铁致敬然而&#xff0c;理想很丰满&#xff…

铁山靠之——HarmonyOS基础 - 1.0

HarmonyOS学习第一章 一、HarmonyOS简介1.1 安装和使用DevEco Studio1.2 环境配置1.3 项目创建1.4 运行程序1.5 基本工程目录1.5.1 工程级目录1.5.2 模块级目录1.5.3 app.json51.5.4 module.json51.5.5 main_pages.json 二、TypeScript快速入门2.1 简介2.2 基础类型2.2.1 布尔值…

vb.net2.0 Hmac-md5加密算法

2019独角兽企业重金招聘Python工程师标准>>> <summary> Hmac-md5加密算法。 </summary> <param name"APassWord">加密串(即密码)</param> <param name"ASourceStr">原始字符串</param> <returns>&l…

解决VS2010 beta2 安装后html标签和script智能提示不起作用的问题

此文已经移至&#xff1a;解决VS2010 beta2 安装后html标签和script智能提示不起作用的问题 安装VS2010 beta2 后&#xff0c;发现正常的html标签的智能提示不起作用&#xff0c;比如<a>,<p>&#xff0c;还有在<script>里面也没有了js的智能提示。 解决办法…

初级Java开发面试必问项!!! 标识符、字面值、变量、数据类型,该学学了!

最近事情太多&#xff0c;没太时间写博客。今天抽空再整理整理面试中的那点事吧&#xff0c;帮助那些正在找工作或想跳槽找工作的学弟学妹们。 前面我己写过多篇推文&#xff0c;相信看过我文章的伙伴们已经了解掌握了不少。从目前流行的开发技术、常见的面试问题以及问题的答…

你还记得当初是怎么对我的吗? | 今日最佳

全世界只有3.14 % 的人关注了青少年数学之旅&#xff08;图源阿粪青&#xff0c;侵权删&#xff09;

4项技巧使你不再为PHP中文编码苦恼

2019独角兽企业重金招聘Python工程师标准>>> PHP程序设计中中文编码问题曾经困扰很多人&#xff0c;导致这个问题的原因其实很简单&#xff0c;每个国家(或区域)都规定了计算机信息交换用的字符编码集&#xff0c;如美国的扩展 ASCII 码&#xff0c;中国的 GB2312-8…

Hello Blazor:(9)Source Generators生成导航菜单

前言最近写了多篇关于Source Generators的文章&#xff0c;发现它确实可以简化我们的部分开发工作。这不&#xff0c;我又盯上了Blazor。问题默认的NavMenu.razor组件用于显示导航菜单&#xff0c;它的部分代码如下&#xff1a;<div class"NavMenuCssClass" oncli…

你绝对没想过原来数学家这么流氓,一言不合就进行暴力证明

全世界只有3.14 % 的人关注了青少年数学之旅1最经典的“无字证明”1989 年的《美国数学月刊》&#xff08;American Mathematical Monthly&#xff09;上有一个貌似非常困难的数学问题&#xff1a;下图是由一个个小三角形组成的正六边形棋盘&#xff0c;现在请你用右边的三种&a…

面试阿里被问到JVM,不逼逼赖赖,直接盘给面试官看!!!

面试阿里被问到JVM&#xff0c;不逼逼赖赖&#xff0c;直接盘给面试官看&#xff01;&#xff01;&#xff01;概述JVM体系结构类加载机制类加载器类加载过程双亲委派机制全盘负责委托机制打破双亲委派机制自定义类加载器实现JVM运行时数据区程序计数器虚拟机栈本地方法栈堆方法…

数学图形(1.20)N叶草

有N个叶子的草 相关软件参见:数学图形可视化工具,使用自己定义语法的脚本代码生成数学图形.该软件免费开源.QQ交流群: 367752815 vertices 1000 t from 0 to (2*PI) r 10 n rand_int2(3, 10) p 1 cos(n*t) sin(n*t)^2 x p*cos(t) y p*sin(t) N叶草面_1 vertices D1:5…

虚拟主机网速测试

ping 命令简单测试网速&#xff0c;我来测一下自己刚买的虚拟主机废话少说&#xff0c;上图&#xff1a;&#xff08;看不清的&#xff0c;点击图片看大图&#xff09;A.中国电信&#xff08;学校的光缆&#xff0c;教师办公专用至少30M&#xff0c;具体数字不清楚&#xff0c;…

Visual Studio 2022 Preview 3和2019 16.11发布

Visual Studio 2022 Preview 3 主要特点个人和团队生产力附加到进程改进新项目设计器黑暗主题提升开发现代应用远程测试新的JavaScript和TypeScript项目类型在指尖上的创新诊断分析同时使用多个GIT存储库详情请参考&#xff1a;https://devblogs.microsoft.com/visualstudio/vi…

梦真的是反的 | 今日最佳

全世界只有3.14 % 的人关注了青少年数学之旅&#xff08;图源神店通缉令&#xff0c;侵权删&#xff09;

面试官问:怎么保证线程安全在对象内存分配过程中不出问题?emmmm 让我想想

Java一门面向对象的语言&#xff0c;在Java中使用的对象都需要被创建出来&#xff0c;在Java中创建一个对象的方法有很多种&#xff0c;但对象在创建过程中都需要进行内存分配。Java对象内存分配过程保证线程安全&#xff0c;对象的内存分配过程就必须进行同步控制。 对象的内…

.NET 6 预览版 7:新功能已完成 ,将专注于改进

.NET 团队的项目经理 Richard Lander在宣布 .NET 6 Preview 7 时说&#xff1a;“这是 .NET 预览的又一季的结束。”, 中文翻译&#xff1a;.NET 6 预览版 7 发布——最后一个预览版。.NET 6.0 是微软统一 .NET 平台的一个重要版本和第一个 LTS&#xff08;长期支持&#xff09…

Windows server 2003 CA配置(一)

CA:Certificate Authority,证书权威机构,也称为证书颁发机构或认证中心)是PKI中受信任的第三方实体.负责证书颁发、吊销、更新和续订等证书管理任务和CRL发布和事件日志记录等几项重要的任务。首先&#xff0c;主体发出证书申请&#xff0c;通常情况下&#xff0c;主体将生成密…

js堆和栈的区别_几个例子理解不同数据类型的堆栈内存处理

如有错误烦请指正js代码的运行环境浏览器 内核(引擎)nodewebview(hybrid&#xff0c;嵌入到手机app里面&#xff0c;在app里面运行)...下面通过几个例子理解不同数据类型的堆栈内存处理js如何运行(示例1)var a 12;var b a;b 13;console.log(a);浏览器能够运行js代码&#xf…

世界上没有后悔药,时间匆匆,从关注它们开始......

全世界只有3.14 % 的人关注了青少年数学之旅在这个资讯丰富且易获取的时代&#xff0c;越来越多的人不愿意花时间阅读书籍&#xff0c;碎片化阅读成了主流。人们获取的东西多而杂&#xff0c;很难系统、全面。海量信息对人是冲击&#xff0c;更是诱惑。谁不想了解天下奇闻&…

什么?面试官问我Java内存模型!这不得给我加薪?

内存模型的基础 通信  线程之间以何种机制来交换信息 共享内存  隐式通信消息传递  显示通信 同步  程序中用于控制不同线程间操作,发生的相对顺序的机制 共享内存  显式同步消息传递  隐式同步 Java线程线程之间是通过共享内存的方式实现通信的. 内存模型的抽…