软件设计模式系列之十八——迭代器模式

1 模式的定义

迭代器模式是一种行为型设计模式,它允许客户端逐个访问一个聚合对象中的元素,而不暴露该对象的内部表示。迭代器模式提供了一种统一的方式来遍历不同类型的集合,使客户端代码更加简洁和可复用。

2 举例说明

为了更好地理解迭代器模式,让我们考虑一个简单的例子:一个图书馆管理系统。图书馆中有许多书籍,而我们希望能够遍历这些书籍并获取相关信息,而不必了解图书馆内部的存储结构。

使用迭代器模式,我们可以将图书馆的书籍封装在一个集合中,并提供一个迭代器,允许我们逐个访问这些书籍,而无需知道其内部是如何组织的。

另外一个例子就是遥控器的遍历频道。
在这里插入图片描述

在电视遥控器上,我们可以使用前进和后退按钮逐个遍历不同的电视频道,而不需要知道电视频道的具体存储方式或频道号码。遥控器充当了迭代器,允许我们浏览不同的频道。

3 结构

迭代器模式通常包括以下几个核心组件:

迭代器接口(Iterator):定义了迭代器的方法,如next()(获取下一个元素)、hasNext()(检查是否还有下一个元素)等。

具体迭代器(ConcreteIterator):实现了迭代器接口,负责实际遍历集合并跟踪当前位置。

聚合接口(Aggregate):定义了创建迭代器对象的方法,通常包括createIterator()。

具体聚合(ConcreteAggregate):实现了聚合接口,负责创建具体的迭代器对象,同时存储元素集合。

4 实现步骤

要实现迭代器模式,可以按照以下步骤进行:
在这里插入图片描述

创建一个迭代器接口(Iterator),并在其中定义迭代方法,如next()和hasNext()。

创建具体的迭代器类(ConcreteIterator),实现迭代器接口,并实现具体的迭代逻辑。

创建一个聚合接口(Aggregate),其中包括一个方法用于创建迭代器对象。

创建具体的聚合类(ConcreteAggregate),实现聚合接口,同时存储元素集合,并实现创建迭代器对象的方法。

5 代码实现

下面是一个简单的Java示例,演示了如何实现迭代器模式:

// 1. 创建迭代器接口
interface Iterator<T> {boolean hasNext();T next();
}// 2. 创建具体迭代器类
class LibraryIterator implements Iterator<String> {private String[] books;private int position = 0;public LibraryIterator(String[] books) {this.books = books;}@Overridepublic boolean hasNext() {return position < books.length;}@Overridepublic String next() {if (hasNext()) {return books[position++];}return null;}
}// 3. 创建聚合接口
interface Aggregate {Iterator<String> createIterator();
}// 4. 创建具体聚合类
class Library implements Aggregate {private String[] books;public Library() {books = new String[]{"Book1", "Book2", "Book3"};}@Overridepublic Iterator<String> createIterator() {return new LibraryIterator(books);}
}public class IteratorPatternExample {public static void main(String[] args) {Library library = new Library();Iterator<String> iterator = library.createIterator();while (iterator.hasNext()) {System.out.println(iterator.next());}}
}

6 典型应用场景

迭代器模式在许多情况下都非常有用,特别是当你需要遍历集合对象而又不想暴露其内部结构时。典型的应用场景包括:

  • 集合类的遍历:
    在这里插入图片描述

用于遍历各种集合类,如数组、列表、集合、树等,而不必暴露其内部实现细节。迭代器模式最常见的用途是在集合类中,以便客户端能够顺序访问集合元素,而无需了解底层数据结构。

  • 数据库查询结果的遍历:

用于遍历数据库查询结果集,以便按需处理每一行记录。迭代器模式可以将数据库查询结果封装成一个集合,并提供迭代器来遍历记录,使代码更清晰和可维护。

  • 图形用户界面中的控件遍历:

用于遍历图形用户界面中的控件、窗口、菜单等,以执行用户交互操作。迭代器模式可以让用户界面库的开发者和设计师更容易地迭代和操作用户界面元素。

  • 菜单管理系统中的菜单项遍历:

用于管理和遍历菜单系统中的菜单项,以显示菜单内容或处理用户选择。迭代器模式可以帮助创建和管理菜单系统,同时让用户能够逐个查看和选择菜单项。

  • 网络爬虫中的网页遍历:

应用场景:用于网络爬虫程序中,遍历网页以抓取信息或执行爬取操作。
说明:迭代器模式可以帮助网络爬虫程序逐个访问并解析网页,以实现数据抓取和分析。

这些典型的应用场景展示了迭代器模式的多样性和灵活性,它可以在许多不同的领域中帮助简化代码,并提高可维护性和可扩展性。

7 优缺点

优点:

分离了集合对象的遍历行为,使得客户端代码更加简洁和可复用。
允许多个客户端同时遍历同一集合,而不会相互干扰。
可以隐藏集合的内部实现,提高了封装性和安全性。

缺点:

增加了类和对象的数量,可能会导致系统复杂性增加。
对于某些简单的集合,使用迭代器模式可能显得过于繁琐。

8 类似模式

与迭代器模式类似的模式包括以下几种:

访问者模式(Visitor Pattern):

访问者模式用于在不改变被访问对象的前提下,定义对这些对象的新操作。它将遍历对象的过程分离出来,并允许你为不同类型的元素定义不同的访问者。迭代器模式和访问者模式都涉及遍历对象的元素集合,但它们的目的不同。迭代器模式是为了提供一种顺序访问集合元素的方式,而访问者模式是为了在不同的元素上执行不同的操作。迭代器模式通常在集合内部实现,而访问者模式则在外部定义了操作。

策略模式(Strategy Pattern):

策略模式定义了一系列算法,将每个算法封装成一个独立的策略类,然后在运行时动态选择使用哪个策略。迭代器模式和策略模式都有助于将算法或行为与客户端代码解耦。迭代器模式通过隐藏集合的遍历方式,策略模式通过动态切换算法来实现解耦。它们都提高了代码的灵活性和可维护性。

观察者模式(Observer Pattern):

观察者模式定义了一种一对多的依赖关系,其中一个对象(主题)状态的改变会通知多个依赖对象(观察者)。迭代器模式和观察者模式都涉及到一种集合元素的变化通知机制。在迭代器模式中,客户端可以逐个遍历集合元素;而在观察者模式中,依赖对象可以订阅主题的状态变化,以获取通知。这些模式都有不同的应用场景和目的,但它们共同点是都有助于提高代码的灵活性、可维护性和可扩展性,同时降低了组件之间的耦合度。选择使用哪个模式取决于具体的问题和需求。

9 小结

迭代器模式是一种非常有用的设计模式,它可以帮助我们遍历各种类型的集合对象,而无需关心其内部结构。通过定义统一的迭代器接口和实现具体的迭代器类,我们可以使客户端代码更加简洁和可维护。此模式在许多领域都有广泛的应用,是每位软件设计师和开发者都应该了解和掌握的设计模式之一。

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

瑞云介绍使用ZBrush和Marmoset工具包制作的风格化巨怪战斗机

Renderbus瑞云渲染的小编今天给大家介绍下Gianluca Squillace使用 ZBrush 和 Marmoset 工具包制作巨怪战士的一些技巧。这位艺术家还贴心地告诉大家&#xff0c;有些步骤是可以省略跳过的&#xff0c;这样就可以节省时间&#xff0c;帮助我们快速完成角色的创作啦。快速有用的步…

tp5连接多个数据库

一、如果你的主数据库配置文件都在config.php里 直接在config.php中中定义db2&#xff1a; 控制器中打印一下&#xff1a; <?php namespace app\index\controller; use think\Controller; use think\Db; use think\Request; class Index extends Controller {public fun…

腾讯mini项目-【指标监控服务重构-会议记录】2023-07-06

7/6 会议记录 Profile4个步骤 解压kafka消息初始化性能事件&#xff0c;分析事件将数据写入kafkaRun 开始执行各stage handler 上报耗时到otel-collector。。。 // ConsumerDispatchHandler consumer // // param msg *sarama.ConsumerMessage // param consumer *databus.K…

Spring实现简单的Bean容器

1.BeanDefinition&#xff0c;用于定义 Bean 实例化信息&#xff0c;现在的实现是以一个 Object 存放对象 public class BeanDefinition {/*** bean对象*/private Object bean;/*** 存放 &#xff08;定义&#xff09;Bean 对象*/public BeanDefinition(Object bean) {this.bea…

折线图geom_line()参数选项

往期折线图教程 图形复现| 使用R语言绘制折线图折线图指定位置标记折线图形状更改 | 绘制动态折线图跟着NC学作图 | 使用python绘制折线图 前言 我们折线的专栏推出一段时间&#xff0c;但是由于个人的原因&#xff0c;一直未进行更新。那么今天&#xff0c;我们也参考《R语…

吃鸡达人分享顶级作战干货,让你的战斗力爆表!

大家好&#xff01;作为一位专业吃鸡行家&#xff0c;我将为大家分享一些热门话题和实用干货&#xff0c;帮助你提高游戏的战斗力&#xff0c;让你在绝地求生中立于不败之地&#xff01; 首先&#xff0c;让我们来谈谈绝地求生作图工具推荐。我们推荐使用一款专业的作图工具&am…

SpringMVC 学习(一)Servlet

本系列文章为【狂神说 Java 】视频的课堂笔记&#xff0c;若有需要可配套视频学习。 1. Hello Servlet (1) 创建父工程 删除src文件夹 引入一些基本的依赖 <!--依赖--> <dependencies><dependency><groupId>junit</groupId><artifactId>…

VSCode 配置 Lua 开发环境(清晰明了)

概述 由于 AutoJS 学得已经差不多了&#xff0c;基本都会了&#xff0c;现在开始向其他游戏脚本框架进发&#xff0c; Lua 语言很强大&#xff0c;就不多说&#xff0c; 按键精灵、触动精灵等等都是用该语言编程脚本的&#xff0c;由于按键精灵、触动精灵 和 AutoJS 类似,不是…

CHATGPT中国免费网页版有哪些-CHATGPT中文版网页

CHATGPT中国免费网页版&#xff0c;一个强大的人工智能聊天机器人。如果你曾经感到困惑、寻求答案&#xff0c;或者需要一些灵感&#xff0c;那么CHATGPT国内网页版可能会成为你的好朋友。 CHATGPT国内免费网页版&#xff1a;你的多面“好朋友” 随着人工智能技术的不断发展&a…

Docker版部署RocketMQ开启ACL验证

一、拉取镜像 docker pull apache/rocketmq:latest 二、准备挂载目录 mkdir /usr/local/rocketmq/data mkdir /usr/local/rocketmq/conf 三、运行 docker run \ -d \ -p 9876:9876 \ -v /usr/local/rocketmq/data/logs:/home/rocketmq/logs \ -v /usr/local/rocketmq/data…

基于微信小程序的场地预约系统设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言系统主要功能&#xff1a;具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09;有保障的售后福利 代码参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计…

【Linux】Linux进程控制

​ ​&#x1f4dd;个人主页&#xff1a;Sherry的成长之路 &#x1f3e0;学习社区&#xff1a;Sherry的成长之路&#xff08;个人社区&#xff09; &#x1f4d6;专栏链接&#xff1a;Linux &#x1f3af;长路漫漫浩浩&#xff0c;万事皆有期待 上一篇博客&#xff1a;【Linux】…

c++ 使用rapidjson对数据序列化和反序列化(vs2109)

RapidJSON是腾讯开源的一个高效的C JSON解析器及生成器&#xff0c;它是只有头文件的C库&#xff0c;综合性能是最好的。 1. 安装 在NuGet中为项目安装tencent.rapidjson 2. 引用头文件 #include <rapidjson/document.h> #include <rapidjson/memorystream.h> #…

java进阶-Netty

Netty 在此非常感谢尚硅谷学院以及韩顺平老师在B站公开课 Netty视频教程 Netty demo代码文件 I/O 说NIO之前先说一下BIO&#xff08;Blocking IO&#xff09;,如何理解这个Blocking呢&#xff1f;客户端监听&#xff08;Listen&#xff09;时&#xff0c;Accept是阻塞的&…

使用SPY++查看窗口信息去排查客户端UI软件问题

目录 1、使用SPY查看窗口的信息 2、使用SPY查看某些软件UI窗口用什么UI组件实现的 2.1、查看海康视频监控客户端安装包程序 2.2、查看华为协同办公软件WeLink 2.3、查看字节协同办公软件飞书 2.4、查看最新版本的Chrome浏览器 2.5、查看小鱼易连视频会议客户端软件 2.6…

WindTerm 安装使用教程【图解】

往期回顾 MobaXtermMobaXterm 安装使用教程【图解】-CSDN博客WindTermWindTerm 安装使用教程【图解】-CSDN博客 一、WindTerm 功能介绍 WindTerm 是一款 Github 上开源的 SSH 终端工具&#xff0c;到目前为止它已经收获了 16.9K 颗星&#xff0c;它是完全可以比肩 MobaXterm 工…

C语言的学习快速入门

可以按照以下步骤进行&#xff1a; 了解基本概念和语法&#xff1a;C语言是一种结构化的编程语言&#xff0c;了解基本的语法规则对于入门非常重要。可以学习关键字、变量、数据类型、运算符、控制结构等基本概念。学习编程环境&#xff1a;选择合适的编程环境&#xff0c;例如…

Spring事务几种的集中原因

Spring事务失效的几种原因 Spring Boot 项目中事务失效的原因可以有多种&#xff0c;这些原因可能导致你的事务无法正常工作。以下是一些常见的事务失效原因的详细讲解&#xff1a; 不使用Transactional注解&#xff1a; 事务需要通过Transactional注解来声明&#xff0c;如果…

基于yolov5的ignore classes训练

本文提到的忽略类别和检测中的忽略类别不一样&#xff0c;前者是在训练中加入忽略类&#xff0c;后者是在检测中仅检测想要的类。 ignore class的定义 我们在标注数据集的时候都是标注的正样本&#xff0c;训练过程中也是这样训练&#xff0c;让网络对正样本计算loss。但我们…

五、C#—字符串

&#x1f33b;&#x1f33b; 目录 一、字符串1.1 字符类型1.2 转义字符1.3 字符串的声明及赋值1.3.1 c# 中的字符串1.3.2 声明字符串1.3.3 使用字符串1.3.4 字符串的初始化1.3.4.1 引用字符串常量之初始化1.3.4.2 利用字符数组初始化1.3.4.3 提取数组中的一部分进行初始化 1.3.…