迭代器模式(Iterator)

迭代器模式是一种行为设计模式,可以在不暴露底层实现(列表、栈或树等)的情况下,遍历一个聚合对象中所有的元素。

Iterator is a behavior design pattern that can traverse all elements of an aggregate object 
without exposing the internal implementation (list, stack, tree, etc.).

结构设计

迭代器模式包含如下角色:
Iterator,迭代器基类,声明遍历聚合对象所需的操作:获取下一个元素、获取当前位置、下一个元素是否存在等。
ConcreteIterator,迭代器实现类,实现遍历聚合对象的算法。
Aggregate,聚合基类,声明一个获取迭代器的接口。
ConcreteAggregate,具体聚合实现类,实现获取一个迭代器的接口并返回一个具体迭代器实例。
Client,客户端,通过聚合基类和迭代器基类的接口与两者进行交互。
迭代器模式类图表示如下:
请添加图片描述

伪代码实现

接下来将使用代码介绍下迭代器模式的实现。

// 1、聚合接口,声明一个获取迭代器的接口,以及元素添加及删除接口
public interface IAggregate {IIterator createIterator();void append(Object element);void removeLast();
}//2、具体聚合实现类,获取一个迭代器的接口,并实现元素添加及删除接口,这里使用数组存储元素
public class ConcreteAggregate implements IAggregate {private String[] elements;private int cursor = -1;public ConcreteAggregate(int size) {elements = new String[size];}@Overridepublic void append(Object element) {cursor++;elements[cursor] = (String) element;}@Overridepublic void removeLast() {elements[cursor] = "";cursor--;}public int getCursor() {return this.cursor;}public String[] getElements() {return this.elements;}@Overridepublic IIterator createIterator() {return new ConcreteIterator(this);}
}// 3、迭代器接口,声明遍历聚合对象所需的操作:获取下一个元素、获取当前位置、下一个元素是否存在等
public interface IIterator {Object first();Object next();boolean hasNext();Object currentItem();
}// 4、迭代器实现类,实现遍历聚合对象的算法,及其他已声明接口
public class ConcreteIterator implements IIterator {private ConcreteAggregate aggregate;private int index;public ConcreteIterator(ConcreteAggregate aggregate) {this.aggregate = aggregate;this.index = 0;}@Overridepublic Object first() {String[] elements = aggregate.getElements();return elements[0];}@Overridepublic Object next() {int cursor = aggregate.getCursor();if (cursor < 0 || index > cursor) {return null;}String[] elements = aggregate.getElements();return elements[index++];}@Overridepublic boolean hasNext() {int cursor = aggregate.getCursor();if (cursor < 0 || index > cursor) {return false;}return true;}@Overridepublic Object currentItem() {int cursor = aggregate.getCursor();if (cursor < 0 || index > cursor) {return null;}String[] elements = aggregate.getElements();return elements[index];}
}// 5、客户端
public class IteratorClient {public void test() {// (1) 创建迭代对象实例IAggregate aggregate = new ConcreteAggregate(10);// (2) 增删元素aggregate.append("hello");aggregate.append("world");aggregate.append("foo");aggregate.removeLast();// (3) 获取迭代器实例IIterator iterator = aggregate.createIterator();// (4) 执行遍历操作while (iterator.hasNext()) {System.out.println(iterator.next());}}
}

适用场景

在以下情况下可以考虑使用迭代器模式:
(1) 当聚合对象的数据结构较复杂,且希望对客户端隐藏其复杂性时(出于易用性或安全性考虑),可考虑使用迭代器模式。迭代器封装了与复杂数据结构进行交互的细节,为客户端提供多个访问集合元素的简单方法。
这种方式不仅对客户端来说非常方便,而且能避免客户端在直接与集合交互时执行错误或有害的操作,从而起到保护集合的作用。
(2) 使用该模式可以减少程序中重复的遍历代码。重要迭代算法的代码往往体积非常庞大。当这些代码被放置在程序业务逻辑中时,它会让原始代码的职责模糊不清,降低其可维护性。因此,
将遍历代码移到特定的迭代器中可使程序代码更加精炼和简洁。
(3) 如果希望代码能够遍历不同的甚至是无法预知的数据结构,可考虑使用迭代器模式。该模式为集合和迭代器提供了一些通用接口。如果在代码中使用了这些接口,那么将其他实现了这些接口的集合和迭代器传递给它时,
它仍将可以正常运行。

优缺点

迭代器模式有以下优点:
(1) 符合单一职责原则。通过将体积庞大的遍历算法代码抽取为独立的类,可对客户端代码和集合进行整理。
(2) 符合开闭原则。可实现新型的集合和迭代器并将其传递给现有代码,无需修改现有代码。
(3) 可以并行遍历同一集合,因为每个迭代器对象都包含其自身的遍历状态。
但是该模式也存在以下缺点:
(1) 如果只与简单的集合进行交互,应用该模式可能会矫枉过正。
(2) 对于某些特殊集合,使用迭代器可能比直接遍历的效率低。
(3) 增加了系统的复杂性。因为迭代器模式将存储数据和遍历数据的职责分离,增加了新的聚合类需要对应增加新的迭代器类,增加了系统的复杂性。

参考

《设计模式 可复用面向对象软件的基础》 Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides 著, 李英军, 马晓星等译
https://design-patterns.readthedocs.io/zh_CN/latest/behavioral_patterns/mediator.html 迭代器模式
https://refactoringguru.cn/design-patterns/mediator 迭代器模式
https://www.runoob.com/design-pattern/mediator-pattern.html 迭代器模式
https://www.cnblogs.com/adamjwh/p/10959987.html 简说设计模式——迭代器模式

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

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

相关文章

排序八卦炉之归并、计数

文章目录 1.归并排序1.1初识代码1.2代码分析1.3复杂度1.4非递归版本1.01.初识代码2.代码分析 1.5非递归版本2.01.初识代码2.代码分析 2.计数排序2.1初始代码2.2代码分析 1.归并排序 1.1初识代码 //归并排序 时间复杂度&#xff1a;O(N*logN) 空间复杂度&#xff1a;O(N) vo…

java中io流、属性集Properties、缓冲流、转换流、序列化和反序列化、打印流、网络编程(TCP通信程序、文件复制案例、文件上传案例、B/S服务案例)

IO流&#xff1a; io流中i表示input输入&#xff0c;o表示output输出&#xff0c;流表示数据&#xff08;字符&#xff0c;字节&#xff0c;1个字符2个字节8个位&#xff09;&#xff1b;这里的输入输出是以内存为基础&#xff0c;将数据从内存中输出到硬盘的过程称为输出&…

复旦大学计算机考研分析

关注我们的微信公众号 姚哥计算机考研 更多详情欢迎咨询 24计算机考研|上岸指南 复旦大学 复旦大学计算机考研招生学院是计算机科学与技术学院&#xff0c;软件学院&#xff0c;工程与应用技术研究院。目前均已出拟录取名单。 复旦大学计算机学科创建于中国计算机事业的起…

C语言数组笔试题(详解)

目录 插入知识&#xff1a; 一.指向函数指针数组的指针 二.回调函数 什么是回调函数&#xff1f; 三.数组笔试题 个人名片&#xff1a; &#x1f43c;作者简介&#xff1a;一名乐于分享在学习道路上收获的大二在校生&#x1f43b;‍❄个人主页&#xff1a;GOTXX &#x1f4…

试用AI生成代码工具Fauxpilot,详细安装过程

设置服务 预先说明 需要预先安装支持NVIDIA的docker,docker compose > 1.28不能再容器里运行&#xff0c;否则出现以下报错&#xff1a; rootc536ca0dbd64:/test/fauxpilot-main# ./setup.sh Checking for curl ... /usr/bin/curl Checking for zstd ... /opt/conda/bin…

计算机网络-性能指标

计算机网络-性能指标 文章目录 计算机网络-性能指标简介速率比特速率 带宽吞吐量时延时延计算 时延带宽积往返时间网络利用率丢包率总结 简介 性能指标可以从不同的方面来度量计算机网络的性能 常用的计算机网络的性能指标有以下8个 速率带宽吞吐量时延时延带宽积往返时间利…

Windows server上用nginx部署vue3项目

Windows server上用nginx部署vue3项目 一、Node中node_modules文件夹及package.json文件的作用说明二、VUE3项目打包三、Windows Server上的Nginx部署 一、Node中node_modules文件夹及package.json文件的作用说明 node_modules是安装node后用来存放用包管理工具下载安装的包的…

【Python | 进阶】提高你的Python技能,99个让代码更简洁、更快的秘密技巧, 确定不来看看?

&#x1f935;‍♂️ 个人主页: AI_magician &#x1f4e1;主页地址&#xff1a; 作者简介&#xff1a;CSDN内容合伙人&#xff0c;全栈领域优质创作者。 &#x1f468;‍&#x1f4bb;景愿&#xff1a;旨在于能和更多的热爱计算机的伙伴一起成长&#xff01;&#xff01;&…

突破传统监测模式:业务状态监控HM的新思路 | 京东云技术团队

一、传统监控系统的盲区&#xff0c;如何打造业务状态监控。 在系统架构设计中非常重要的一环是要做数据监控和数据最终一致性&#xff0c;关于一致性的补偿&#xff0c;已经由算法部的大佬总结过就不再赘述。这里主要讲如何去补偿&#xff1f;补偿的方案哪些&#xff1f;这就…

Vue + ElementUI 实现可编辑表格及校验

效果 完整代码见文末 实现思路 使用两个表单分别用于实现修改和新增处理。 通过一个editIndex变量判断是否是编辑状态来决定是否展示输入框&#xff0c;当点击指定行的修改后进行设置即可&#xff1a; <el-table-columnv-for"(column, index) in columns":key&qu…

Android 开发代码规范

一. AndroidStudio开发工具规范 使用最新的稳定版本.统一文件的编码格式为utf-8. 清除每个类里面的无效的import导包.代码样式统一,比如&#xff0c;tab缩进4个空格&#xff0c;或者 tab size等如果没有特殊情况使用默认的配置即可。每行字数每行字符数不得超过 160 字符&…

SpringMVC -- REST风格开发,RESTful快速开发、RESTful注解开发

&#x1f40c;个人主页&#xff1a; &#x1f40c; 叶落闲庭 &#x1f4a8;我的专栏&#xff1a;&#x1f4a8; c语言 数据结构 javaweb 石可破也&#xff0c;而不可夺坚&#xff1b;丹可磨也&#xff0c;而不可夺赤。 REST 一、REST简介1.1REST风格简介 二、RESTful入门案例2.…

MySQL日期常见的函数

-- 获取当天日期 -- 2023-06-20 select curdate();-- 获取当天年月日时分秒 select now();-- 日期运算 -- 2024-06-20 17:04:17 select date_add(now(),interval 1 year);-- 日期比较 -- 0 select datediff(now(),now());-- 日期MySQL对于日期类型数据如何查询 -- 获取指定日期…

IDEA SpringBoot Maven profiles 配置

IDEA SpringBoot Maven profiles 配置 IDEA版本&#xff1a; IntelliJ IDEA 2022.2.3 注意&#xff1a;切换环境之后务必点击一下刷新&#xff0c;推荐点击耗时更短。 application.yaml spring:profiles:active: env多环境文件名&#xff1a; application-dev.yaml、 applicat…

2023年 Java 面试八股文(20w字)

目录 第一章-Java基础篇 1、你是怎样理解OOP面向对象 难度系数&#xff1a;⭐ 2、重载与重写区别 难度系数&#xff1a;⭐ 3、接口与抽象类的区别 难度系数&#xff1a;⭐ 4、深拷贝与浅拷贝的理解 难度系数&#xff1a;⭐ 5、sleep和wait区别 难度系数&a…

CI/CD—Docker初入门学习

1 docker 了解 1 Docker 简介 Docker 是基于 Go 语言的开源应用容器虚拟化技术。Docker的主要目标是build、ship and run any app&#xff0c;anywhere&#xff0c;即通过对应用组件的封装、分发、部署、运行等生命周期的管理&#xff0c;达到应用组件级别的一次封装、到处运…

MySQL索引3——Explain关键字和索引使用规则(SQL提示、索引失效、最左前缀法则)

目录 Explain关键字 索引性能分析 Id ——select的查询序列号 Select_type——select查询的类型 Table——表名称 Type——select的连接类型 Possible_key ——显示可能应用在这张表的索引 Key——实际用到的索引 Key_len——实际索引使用到的字节数 Ref ——索引命…

vs导出和导入动态库和静态库

1. 动态库和导出和导入 1.1 动态库的导出 1. 创建新项目 新建新项目&#xff0c;选择动态链接库&#xff08;DLL&#xff09;。 填写项目名称&#xff0c;并选择项目保存的路径&#xff0c;然后点击创建。 创建完成后&#xff0c;会自动生成如下所示文件&#xff0c;可以根据…

PostgreSQL-数据库命令

PostgreSQL-数据库命令 介绍 一个数据库是一个或多个模式的集合&#xff0c;而模式包含表、函数等。因此&#xff0c;完整的逻辑组织结构层次是服务器实例&#xff08;PostgreSQL Server&#xff09;、数据库&#xff08;Database&#xff09;、模式&#xff08;Schema&#…

jmeter 5.1彻底解决中文上传乱码

1.修改源码,然后重新打jar包,就是所有上传文件名重新获取文件名 参考链接:多种Jmeter中文乱码问题处理方法 - 51Testing软件测试网 2.修改Advanced,必须选java