三分钟掌握“迭代器模式”——轻松搞定设计模式

迭代器模式的官方定义:

迭代器模式提供了一种方法,它能够顺序访问一个集合对象中的各个元素,并且又不暴露该对象的内部结构。

不使用迭代器模式实现容器的迭代:

当我们拿到一个含有集合的对象时,如果我们想要遍历对象中的集合,就必须要知道对象的内部结构,然后使用for循环遍历对象中的集合。而且当我们需要换一种遍历方式的时候(如:顺序遍历换成逆序遍历),需要修改客户端的代码,这就违背了“封闭-开放原则”。但如果使用了迭代器模式之后,需要换迭代方式时,只需要增加一个迭代器类,然后稍微修改一下集合对象中的代码,而客户端代码一句也不要动;也就是说,使用了迭代器模式之后,当需要更换迭代方式的时候,我们再增加一个类,而不是修改代码,从而体现了“开放-封闭原则”。

PS:开放-封闭原则:开放扩展,封闭更改。代码一旦写完就不要再去修改,若要增加功能,通过拓展继承体系(也就是增加类)来实现。

迭代器模式类图:

1.首先需要有一个存放许多数据的容器,我们把它称为Collection;其次需要再创建一个类,专门用来遍历容器中的数据,我们把这个类称为Iterator;而且Iterator中包含了遍历容器的一些基本函数。

2.由于容器的内部构造都不尽相同,但他们都需要使用迭代器遍历,因此我们抽象出容器们的公共接口,这个接口中只有一个获取迭代器的函数:iterator();

3.由于每个容器内部构造都不一样,所以迭代这些容器的迭代器的具体实现也不一样,所以我们需要为每一个容易简历一个专门的迭代器类,针对每种容器的内部结构,实现了Iterator接口中的函数。

4.由于具体的迭代器需要知道它所服务的容器的内部结构,所以要在构造迭代器的时候将容器的对象传给迭代器,迭代器拿到具体的容器对象之后,就可以根据这个容器的特性重写next、hasNext、first这些函数了。

5.最后,当迭代器和容器都写好之后,就可以交付给客户使用了。

客户通过容器的iterator函数获得该容器对应的迭代器对象,然后使用该迭代器对象的一些函数就可以遍历容器元素了。

PS:客户通过调用容器对象的iterator函数创建该容器对应的Iterator对象时,该容器的对象将会传递给Iterator对象:

private Iterator it; 

@Override

public Iterator iterator() {

this.it = new AIterator(this);

return this.it;

}

当AIterator对象获取到它所服务的容器对象之后,才能针对该容器的结构重写next、hasNext、first这些函数。

迭代器模式的好处:

1.如果要更换一个具体容器的迭代方式的时候,客户端不需要做任何改动,还是这么写:

Iterator it = collection.iterator();

while(it.hasNext()){

   System.out.println(it.next());

}

我们只需要:

a)再创建一个迭代器类,重写里面的next、hasNext、first这些函数;

b)然后让容器类的iterator函数中创建Iterator对象时,将“旧的Iterator”换成“新的Iterator”

public Iterator iterator(){

this.it = new 新的Iterator();

}

因此,一个容器的迭代方式换了之后,不影响客户端的代码,降低了客户端与Iterator类和Collection类的耦合。

2.迭代器模式将集合对象的遍历行为单独封装在一个类中,这样既不暴露集合的内部结构,又可以使外部代码透明地访问集合内部的数据。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Java Web

Java学习笔记(2)——数据类型

终于要写点干货了,其实思考了很久下面一篇文章要写什么,主要的纠结点在于,既想要分享那些精美的知识,又怕这些知识不太好嚼。后来想想还是对初学者不太好友算了..一...

2783
来自专栏极客猴

Python 正则表达式

我们能够使用 urllib 向网页请求并获取其网页数据。但是抓取信息数据量比较大,我们可能需要其中一小部分数据。对付刚才的难题,就需要正则表达式出马了。正则表达...

992
来自专栏决胜机器学习

PHP数据结构(二十二) ——快速排序

PHP数据结构(二十二)——快速排序 (原创内容,转载请注明来源,谢谢) 一、概述 前面的插入排序,都是以移动的方式进行排序。快速排序,则是以交换的方式进行...

3939
来自专栏成猿之路

Java面试题基础篇

1256
来自专栏互联网开发者交流社区

面向对象的Java实现

1-1:封装 a.为什么需要封装(封装可以是数据方便维护、增加实用性、方便扩展等等。通过面向对象的思想,模拟现实生活中的事物。) b.什么是封装(封装就是将...

861
来自专栏信数据得永生

JavaScript 编程精解 中文第三版 三、函数

3347
来自专栏java一日一条

如何读懂并写出装逼的函数式代码

今天在微博上看到了 有人分享了下面的这段函数式代码,我把代码贴到下面,不过我对原来的代码略有改动,对于函数式的版本,咋一看,的确令人非常费解,仔细看一下,你可能...

682
来自专栏和蔼的张星的图像处理专栏

55. 比较字符串

比较两个字符串A和B,确定A中是否包含B中所有的字符。字符串A和B中的字符都是 大写字母 样例 给出 A = "ABCD" B = "ACD",返回 tru...

1401
来自专栏鸿的学习笔记

Python和Scala的定义变量

每一门的编程语言背后都代表着某一种特别的哲学,由这一哲学进而设计出属于这门程序语言的语法,Python和Scala也不例外。我们从变量的定义去一窥Python和...

982
来自专栏小詹同学

Leetcode打卡 | No.014 最长公共前缀

欢迎和小詹一起定期刷leetcode,每周一和周五更新一题,每一题都吃透,欢迎一题多解,寻找最优解!这个记录帖哪怕只有一个读者,小詹也会坚持刷下去的!

1022

扫码关注云+社区

领取腾讯云代金券