设计模式——迭代器模式

article/2025/10/3 17:08:52

迭代器模式

1.迭代器模式动机及定义

1.1模式动机

        聚合对象用于存储多个对象,在软件开发中应用广泛,为了更加方便地操作聚合对象,在很多编程语言中都提供了迭代器(Iterator),迭代器本身也是一个对象,它的工作就是遍历并获取聚合中的对象,而程序员不必关心该聚合的内部结构。

        一个聚合对象,如一个列表(List)或者一个集合(Set),应该提供一种方法来让别人可以访问它的元素,而又不需要暴露它的内部结构,如同电视遥控器,我们可以通过使用它来方便地切换频道,但是不需要知道这些频道在电视机中的存储方式。此外,针对不同的需要,可能还要以不同的方式遍历整个聚合对象,但是我们并不希望在聚合对象的抽象层接口中充斥着各种不同遍历的操作。怎样遍历一个聚合对象,又不需要了解聚合对象的内部结构,还能够提供多种不同的遍历方式,这就是迭代器模式所要解决的问题。

        在迭代器模式中,提供一个外部的迭代器来对聚合对象进行访问和遍历,迭代器定义了一个访问该聚合元素的接口,并且可以跟踪当前遍历的元素,了解哪些元素已经遍历过而哪些没有。有了迭代器模式,我们会发现当对一个复杂的聚合对象的操作会变得如此简单。

        如果将电视机看成一个频道的集合,那么迭代器对应于电视机遥控器,可以使用遥控器对电视频道进行操作,如返回上一个频道、跳转到下一个频道或者转向指定的频道。使用遥控器可以方便人们对电视频道进行操作,而且不需要关心这些频道如何存储在电视机中。在这里,电视机对应于聚合对象,而遥控器对应于迭代器。

1.2模式定义

        迭代器模式(Iterator Pattern)定义:提供一种方法来访问聚合对象,而不用暴露这个对象的内部表示,其别名为游标(Cursor)。迭代器模式是一种对象行为型模式。

        英文定义:“Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation.”

2.迭代器模式结构与分析

2.1模式结构

 

图1 迭代器模式结构图

迭代器模式包含如下角色。

1.Iterator(抽象迭代器)

        抽象迭代器定义了访问和遍历元素的接口,一般声明如下方法:用于获取第一个元素的first(),用于访问下一个元素的next(),用于判断是否还有下一个元素的hasNext(),用于获取当前元素的currentItem(),在其子类中实现这些方法。

2.ConcreteIterator(具体迭代器类)

        具体迭代器实现了抽象迭代器接口,完成对聚合对象对遍历,同时在对象聚合进行遍历时跟踪其当前位置.

3.Aggregate(抽象聚合类)

        抽象聚合类用于存储对象,并定义创建相应迭代器对象的接口,声明一个createIterator()方法用于创建一个迭代器对象。

4.ConcreteAggregate(具体聚合类)

        具体聚合类实现了创建相应迭代器的接口,实现了在聚合类中声明的createIterator()方法,该方法返回一个与该具体聚合对应的具体迭代器ConcreteIterator实例。

2.2模式分析

        根据“单一职责原则”,在面向对象设计时,对象承担的职武越少,则该对象的稳定性就越好,受到的约束也就越少,复用也就越方便。职责分离可以最大限度地减少彼此之间的耦合程度,从而建立一个松散耦合的对象网络职责分离的要点是对被分离的职责进行封装,并以抽象的方式建立起彼此之间的关系。

        以聚合对象为例,聚合是一个管理和组织数据对象的数据结构。这就表明聚合首先应具备一个基本功能,即存储数据,这其中包含存储数据的类型、存储空间的大小、存储空间的分配,以及存储的方式和顺序。如果不具备这些特点,则该对象就不能称为聚合对象。也就是说,存储数据是聚合对象最基本的职责。然而,聚合对象除了能够存储数据外,还必须提供遍历访问其内部数据的方式,同时这些遍历方式可能会根据不同的情形提供不同的实现,如正向遍历或逆向遍历等。因此,聚合对象主要拥有两个职责:一是存储内部数据;二是遍历内部数据。但是前者是聚合对象的基本功能,而后者是可以分离的。因此,我们将遍历聚合对象中数据的行为提取出来,封装到一个达代器中,通过专门的迭代器来遍历聚合对象的内部数据,这就是迭代器模式的本质。迭代器模式是“单一职责原则”的完美体现。

3.迭代器模式实例与解析

        题目:某商品管理系统的商品名称存储在一个字符串数组中,现需要自定义一个双向迭代器(MyIterator)实现对该商品名称数组的双向(前向和后向)遍历。绘制类图并编程实现(设计方案必须符合DIP)

3.1实例类图

 

3.2实例代码及解释

1.抽象迭代器类MyIteratord(抽象迭代器类)

public interface MyIterator {void setChannel(int i);void next();void previous();Object currentChannel();boolean isFirst();boolean isLast();}

        MyIterator作为抽象迭代器类,在其中声明了迭代器所具有的方法,包括指针的移动方法与对象的获取方法,以实现对集合对象的遍历。

2.抽象聚合类Store(商店类)

public interface Store {MyIterator createIterator();}

        该类是抽象聚合类,可以将商品看成一个商店的集合,在商店类中声明了用于创建商店对象的createIterator()方法。

3.具体聚合类WDStore(万达商店类)

package Iterator_pattren;public class WDStore implements Store{private Object[] obj = {"电脑","手机","平板","键盘","耳机"};public MyIterator createIterator() {return new WDIterator();}private class WDIterator implements MyIterator{private int currentIndex = 0;@Overridepublic void setChannel(int i) {currentIndex = i;}@Overridepublic void next() {if (currentIndex < obj.length){currentIndex++;}}@Overridepublic void previous() {if (currentIndex > 0){currentIndex--;}}@Overridepublic Object currentChannel() {return obj[currentIndex];}@Overridepublic boolean isFirst() {return currentIndex == 0;}public boolean isLast() {return currentIndex == obj.length;}}}

        WDStore是具体聚合类,在WDStore中定义了一个数组用于存储电视频道,具体迭代器类WDIterator作为WDStore的内部类,在WDIterator中实现了在抽象迭代器中声明的用于遍历聚合对象的方法,而WDStore作为抽象聚合类的子类实现了在抽象聚合类中声明的方法createIterator(),用于返回一个具体迭代器对象。

3.3辅助代码

客户端测试类Client如下:

import factor_method_pattern.XMLUtil;public class Client {public static void show(WDStore store){MyIterator i = store.createIterator();System.out.println("商品遍历:");while (!i.isLast()){System.out.println(i.currentChannel().toString());i.next();}}public static void reverseShow(WDStore store){MyIterator i =store.createIterator();i.setChannel(5);System.out.println("逆序商品遍历:");while (!i.isFirst()){i.previous();System.out.println(i.currentChannel().toString());}}public static void main(String[] args) {WDStore store;store = (WDStore) XMLUtil.getBean();show(store);System.out.println("---------------------");reverseShow(store);}}

Config.xml代码:

<?xml version="1.0"  ?><config ><className>Iterator_pattren.WDStore</className></config>

3.4结果

4.迭代器模式效果与应用

4.1 迭代器模式的优点

        (1)它支持以不同的方式遍历一个聚合对象。对于复杂的聚合对象可用多种方法来进行遍历,在迭代器模式中只需要用一个不同的迭代器来替换原有迭代器即可改变遍历算法,也可以自己定义迭代器的子类以支持新的遍历方式。

        (2)迭代器简化了聚合类。因为引入了迭代器,在原有的聚合对象中不需要再自行提供遍历等数据操作方法,这样可以简化聚合类等设计。

        (3)在同一个聚合上可以有多个遍历。由于每个迭代器都保持自己都遍历状态,因此可以同时对一个聚合对象进行多个遍历操作。

        (4)在迭代器模式中,增加新的聚合类和迭代器类都很方便,无须修改原有代码,满足“开闭原则”的要求。

4.2迭代器模式的缺点

        (1)由于迭代器模式将存储数据和遍历数据的职责分离,增加了新的聚合类需要对应增加新的迭代器类,类的个数成对增加,这在一定程度上增加了系统的复杂性。

4.3模式适用环境

在以下情况可以使用迭代器模式。

  1. 访问一个聚合对象的内容而无须暴露它的内部表示。将聚合对象的访问与内部数据的存储分离,使得访问聚合对象时无须了解其内部实现细节。
  2. 需要为聚合对象提供多种遍历方式。
  3. 为遍历不同的聚合结构提供一个统一的接口。当需要扩展聚合结构或者给聚合结构增加新的遍历方式时可以使用迭代器模式,它提供了聚合结构和迭代器的抽象定义。


http://chatgpt.dhexx.cn/article/kHEu8TIk.shtml

相关文章

【设计模式】迭代器模式 ( 简介 | 适用场景 | 优缺点 | 代码示例 )

文章目录 一、迭代器模式简介二、迭代器模式适用场景三、迭代器模式优缺点四、迭代器模式和访问者模式五、迭代器模式代码示例1、迭代器接口2、迭代器实现3、集合元素实例类4、集合管理接口5、集合管理实现类6、测试类 一、迭代器模式简介 迭代器模式 : 提供一种方法 , 顺序访问…

SOME/IP报文格式-Payload

Payload [variable size] In the payload field the parameters are carried. Parameter被携带于Payload字段中 。The size of the SOME/IP payload field depends on the transport protocol used. With UDP the SOME/IP payload shall be between 0 and 1400 Bytes. The lim…

IP协议数据报格式详解

&#x1f431;‍&#x1f3cd;写博客的主要原因是为了巩固所学知识 &#x1f431;‍&#x1f3cd; IP数据报格式 4位版本号(Version) 由4比特组成&#xff0c;用来指定IP协议的版本。IPv4的版本号为4&#xff0c;即0100。 4位首部长度(Header Length) 由4比特组成&#xff0c;表…

IP数据报文格式

【转载】http://blog.csdn.net/shinezhang86/article/details/47145907 由于记性不好的原因, 一直对报文格式的字段记的不是很牢固, 故花了一天时间学习IP报文格式, 第二天来总结. 过两天再继续学习TCP和UDP. IP报文格式如下图所示(图片来源—百度百科): 版本(Version, 4bit):为…

IPv6报文格式

IPv6报文 IPv6报文分为两大部分&#xff1a;报头&#xff0c;负载。 报头 IPv6的报头是固定的320bit&#xff0c;不同与IPv4&#xff0c;IPv6把可选项从标准头部中移除&#xff0c;标准头部包含着版本号、流量类型、流标签、负载数据的长度、下一协议报头、生存时间&#xff08…

IP 协议报文格式 【IPv4】

前言: IP 数据报文由首部&#xff08;称为报头&#xff09;和数据两部分组成&#xff1b;首部的前一部分是固定长度&#xff0c;共 20 字节&#xff0c;是所有 IP 数据报必须具有的&#xff1b;在首部的固定部分的后面是一些可选字段&#xff0c;其长度是可变的 每个 IP 数据报…

TCP和UDP以及IP报文格式

TCP和UDP以及IP报文格式 TCP报文&#xff1a; 源端口&#xff1a; 数据发送方的端口号。 目的端口&#xff1a; 数据接受方的端口号。 序号&#xff1a;本数据报文中的的第一个字节的序号&#xff08;在数据流中每个字节都对应一个序号&#xff09;。 确认号&#xff1a;希望…

ipv4 报文格式中文描述

ipv4 报文格式中文描述 ipv4 英文描述 第一行 报文头部 20 byte 选项 40 byte ver 版本&#xff1a;4位 ipv40100hlen 头部长度&#xff1a;4bit 固定头部 选项 用4byte 为单位标记头部长度 &#xff08;5-15&#xff09;0101-1111tos服务类型&#xff1a;8位total length 报…

以太网 以太网帧格式与IP报文分片

2.1.0 以太网 以太网帧格式与IP报文分片 一、以太网数据帧信息简介 以太网有两种类型的数据帧&#xff0c;一种是Ethernet_II另一种是IEEE802.3。 两者并没有明确的规定两种类型的使用场景&#xff0c;通常都是由协议/应用程序的开发者定义的。 通过观察发现&#xff1a; …

SOME/IP报文格式-Message ID

–回目录页 SOME/IP报文格式-Message ID Message ID [32 Bit] The Message ID is a 32 Bit identifier that is used to dispatch the RPC call to a method of an application and to identify an event. The Message ID has to uniquely identify a method or event of a …

TCP/IP报文格式详解

1.端口号   标记同一台计算机上的不同进程   源端口&#xff1a;占2个字节&#xff0c;源端口和IP的作用是标记报文的返回地址。   目的端口&#xff1a;占2个字节&#xff0c;指明接收方计算机上的应用程序接口。   TCP报头中的源端口号和目的端口号同IP报头中的源…

ping内网流程以及ARP,ICMP,IP报文格式

ping内网流程 正常ping流程 A->B arp广播报文格式&#xff1a; 以太网目的MAC 以太网源MAC 帧类型 硬件类型 4 6 OP 发送端以太网MAC 发送端IP地址 目的MAC 目的IP FF-FF-FF-FF-FF-FF 00-50-56-C0-00-01 0806 0800 1 00-50-56-C0-00-01 1.1.1.1 00-00-0…

TCP,IP,UDP等各种报文格式

1.TCP&#xff1a;全双工&#xff0c;传输层协议 源端口和目的端口&#xff1a;各占2个字节&#xff0c;是运输层与应用层的服务接口。 序号&#xff1a;占4个字节。TCP连接传送的数据流中的每一个字节都被编上一个序号。首部中序号字段的值指的是本报文段所发送的数据的第一个…

IP报文格式及各字段的意义

IP数据包由报头和数据两部分组成。报头的前一部分是固定长度&#xff0c;共20字节。在报头的固定部分的后面是可选部分——IP选项和填充域。 首部各字段的含义如下 1、版本 占4位&#xff0c;指IP协议的版本。 2、报头长度 占4位&#xff0c;该字段的单位是32位字&#xff08;1…

IP报文格式和实例分析

上面是IP的报文格式&#xff0c;接下来我们先说明各个字段的意义。然后&#xff0c;用Etheral软件转包分析IP的报文格式。 1.版本&#xff1a;ip报文中&#xff0c;版本占了4位&#xff0c;用来表示该协议采用的是那一个版本的ip&#xff0c;相同版本的ip才能进行通信。一般此…

TCP/IP协议中IP数据保报文格式详解

在 TCP/IP 协议中&#xff0c;使用 IP 协议传输数据的包被称为 IP 数据包&#xff0c;每个数据包都包含 IP 协议规定的内容。IP 协议规定的这些内容被称为 IP 数据报文&#xff08;IP Datagram&#xff09;或者 IP 数据包。 IP 数据报文由首部&#xff08;称为报头&#xff09;…

TCP/IP报文格式及通讯

目录 1 分层结构 1.1 PHY物理层 1.2 MAC层&#xff08;LLC逻辑链路层&#xff09; 1.3 IP层&#xff08;net网络层&#xff09; 1.3.1 IP报路由时MAC变IP不变 1.3.2 ARP原理 1.3.3 IP报拆分 1.3.4 生存时间 1.3.5 协议种类 1.3.7 划分子网 1.4 TCP报文、UDP报文 1.5 应…

TCP/IP 报文格式(IP数据包、TCP报头、UDP报头)

TCP/IP 报文格式&#xff08;IP数据包、TCP报头、UDP报头&#xff09; 一、IP包格式 IP数据包&#xff0c;是一种可以变长的分组&#xff0c;由首部与数据负载组成。首部长度为20-60字节&#xff08;Byte&#xff09;&#xff0c;后40字节是可选的&#xff0c;但长度不固定&a…

SOMEIP报文格式部分字段概述(二)

书非借而不能读也&#xff01; 为了提高效率&#xff0c;现在参考了某网友的&#xff08;忘记来源了&#xff09;相关文章。 【SOMEIP报文格式部分字段概述】 【Message ID】 Message ID是一个32位标识符&#xff0c;用于将RPC调用分派给应用程序的method并识别event 。 Mess…

【TCP/IP详解】IP报文格式

我将工作中用到的报文格式进行了汇总&#xff0c;方便查阅&#xff1a; 【TCP/IP协议】各层报文首部数据格式汇总 解析: 4位版本&#xff1a;目前的协议版本号是4&#xff0c;因此IP有时也称作IPv4。4位首部长度&#xff1a;普通的IP首部长为20个字节&#xff0c;除非含有选项字…