迭代器模式(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.mzph.cn/news/24903.shtml

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

相关文章

【二分查找】74. 搜索二维矩阵

74. 搜索二维矩阵 解题思路 方法1 将二维数组转换为一维数组使用二分查找 class Solution {public boolean searchMatrix(int[][] matrix, int target) {// 使用二分查找// 将矩阵写入一个数组中 然后使用二分查找算法int[] a new int[matrix.length * matrix[0].length];i…

机器学习常用Python库安装

机器学习常用Python库安装 作者日期版本说明Dog Tao2022.06.16V1.0开始建立文档 文章目录 机器学习常用Python库安装Anaconda简介使用镜像源配置 Pip简介镜像源配置 CUDAPytorch安装旧版本 TensorFlowGPU支持说明 DGL简介安装DGLLife RDKitscikit-multilearn Anaconda 简介 …

Python 程序设计入门(004)—— 赋值运算符与常用函数

Python 程序设计入门&#xff08;004&#xff09;—— 赋值运算符与常用函数 目录 Python 程序设计入门&#xff08;004&#xff09;—— 赋值运算符与常用函数一、赋值运算符二、常用的数学函数1、round() 函数2、pow() 函数3、divmod() 函数 三、字符串与 str() 函数1、字符串…

UEditorPlus v3.3.0 图片上传压缩重构,UI优化,升级基础组件

UEditor是由百度开发的所见即所得的开源富文本编辑器&#xff0c;基于MIT开源协议&#xff0c;该富文本编辑器帮助不少网站开发者解决富文本编辑器的难点。 UEditorPlus 是有 ModStart 团队基于 UEditor 二次开发的富文本编辑器&#xff0c;主要做了样式的定制&#xff0c;更符…

C++经典排序算法详解

目录 一、选择排序 二、冒泡排序 三、插入排序 一、选择排序 选择排序 选择排序&#xff08;Selection sort&#xff09;是一种简单直观的排序算法。它的工作原理是&#xff1a;第一次从待排序的数据元素中选出最小&#xff08;或最大&#xff09;的一个元素&#xff0c;存…

解决vite+vue3项目npm装包失败

报错如下&#xff1a; Failed to remove some directories [ npm WARN cleanup [ npm WARN cleanup D:\\V3Work\\v3project\\node_modules\\vue, npm WARN cleanup [Error: EPERM: operation not permitted, rmdir D:\V3Work\v3project\node_modules\vue\reactivity\…

题解 | #B.Distance# 2023牛客暑期多校6

B.Distance 贪心(?) 题目大意 对于两个大小相同的多重集 A , B \mathbb{A},\mathbb{B} A,B &#xff0c;可以选择其中任一元素 x x x 执行操作 x x 1 xx1 xx1 任意次数&#xff0c;最少的使得 A , B \mathbb{A},\mathbb{B} A,B 相同的操作次数记为 C ( A , B ) C(\m…

嵌入式开发学习(STC51-13-温度传感器)

内容 通过DS18B20温度传感器&#xff0c;在数码管显示检测到的温度值&#xff1b; DS18B20介绍 简介 DS18B20是由DALLAS半导体公司推出的一种的“一线总线&#xff08;单总线&#xff09;”接口的温度传感器&#xff1b; 与传统的热敏电阻等测温元件相比&#xff0c;它是一…

虚函数表(vtable)

虚函数表&#xff08;通常简称为 vtable&#xff09;是 C 用于实现多态行为的一种机制。当一个类定义了虚函数或者继承了虚函数&#xff0c;编译器会为该类生成一个虚函数表。下面详细介绍虚函数表及其工作原理&#xff1a; 1. 什么是虚函数表&#xff1f; 虚函数表是一个存放…

关于Express 5

目录 1、概述 2、Express 5的变化 2.1 弃用或删除内容的列表&#xff1a; app.param&#xff08;name&#xff0c;fn&#xff09;名称中的前导冒号&#xff08;&#xff1a;&#xff09; app.del() app.param&#xff08;fn&#xff09; 复数方法名 res.json&#xff0…

Codeforces Round 890 (Div. 2) D. More Wrong(交互题 贪心/启发式 补写法)

题目 t(t<100)组样例&#xff0c;长为n(n<2000)的序列 交互题&#xff0c;每次你可以询问一个区间[l,r]的逆序对数&#xff0c;代价是 要在的代价内问出最大元素的位置&#xff0c;输出其位置 思路来源 neal Codeforces Round 890 (Div. 2) supported by Constructo…

springboot工程测试临时数据修改技巧

目录 properties临时属性测试注入 args临时参数测试注入 bean配置类属性注入&#xff08;Import&#xff09; SpringBootTest是一个注解&#xff0c;用于测试Spring Boot应用程序。它可用于指示Spring Boot测试应用程序的启动点&#xff0c;并为测试提供一个可用的Spring应用…

Godot 4 源码分析 - Path2D与PathFollow2D

学习演示项目dodge_the_creeps&#xff0c;发现里面多了一个Path2D与PathFollow2D 研究GDScript代码发现&#xff0c;它主要用于随机生成Mob var mob_spawn_location get_node(^"MobPath/MobSpawnLocation")mob_spawn_location.progress randi()# Set the mobs dir…

【C语言】初阶完结练习题

&#x1f388;个人主页&#xff1a;库库的里昂 &#x1f390;CSDN新晋作者 &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏 ✨收录专栏&#xff1a;C语言初阶 ✨其他专栏&#xff1a;代码小游戏 &#x1f91d;希望作者的文章能对你有所帮助&#xff0c;有不足的地方请在评论…

Misc取证学习

文章目录 Misc取证学习磁盘取证工具veracryto挂载fat文件DiskGenius 磁盘取证例题[RCTF2019]disk 磁盘[](https://ciphersaw.me/ctf-wiki/misc/disk-memory/introduction/#_2)内存取证工具volatility 内存取证例题数字取证赛题0x01.从内存中获取到用户admin的密码并且破解密码 …

ffmpeg视频音频命令

视频音频合并 视频音频合并&#xff0c;以视频时间为主&#xff0c;音频短了循环 方法1&#xff1a;混音&#xff0c;视频权重0&#xff0c;volume调节音量&#xff0c;aloop无限循环&#xff0c;duration:first为第一个素材的长度 ffmpeg -i video.mp4 -i audio.mp3 -filter_…

P3754. [NOIP2002 提高组] 字串变换

本题思路 纯bfs&#xff0c;注意一个字符中有多个相同的可变字符即可。 代码 void solve() {string a,b; cin>>a>>b; // 读入起始串和结束串vector<pair<string,string>> mss; // 可能有一个字符串的多个变换规则&#xff0c;不能用map&#xff0c;…

如何搭建一个成功的家具小程序

家具行业近年来发展迅猛&#xff0c;越来越多的消费者开始选择在小程序商城上购买家具。因此&#xff0c;制作一款家具小程序商城成为了许多家具商家的必然选择。那么&#xff0c;如何制作一款个性化、功能齐全的家具小程序商城呢&#xff1f;下面将为大家介绍一种简单且高效的…

观察者模式(C++)

定义 定义对象间的一种一对多(变化)的依赖关系&#xff0c;以便当一个对象(Subject)的状态发生改变时&#xff0c;所有依赖于它的对象都得到通知并自动更新。 ——《设计模式》GoF 使用场景 一个对象&#xff08;目标对象&#xff09;的状态发生改变&#xff0c;所有的依赖对…

首页文章列表分页模板渲染(Go搭建qiucode.cn 之六)

笔者小站:秋码记录 距离上一篇已过去好久了,当然咯,秋码记录 也已换了本来的面貌,其中林林种种,不可道于外人乎!然而之所以会有第六篇,完全得益于那位订阅的粉丝,也是他唤起了我应该将Go搭建qiucode.cn写完,在此我由衷的感谢这位,且作为本专栏首位订阅者。 接上一篇,…