迭代器模式【行为模式C++】

1.简介

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

迭代器的意义就是将这个行为抽离封装起来,这样客户端只需要调用合适的迭代器,来进行对应的遍历,而不用自己去实现这一行为。

2、结构


迭代器模式主要由以下几个结构组成:

迭代器(Iterator):定义访问和遍历聚合对象中元素的接口,包括获取下一个元素、判断是否还有下一个元素等方法。
具体迭代器(Concrete Iterator):实现迭代器接口,存储聚合对象的当前状态,负责遍历聚合对象中的元素。
聚合对象(Aggregate):定义创建相应迭代器对象的接口,一般是一个集合类,如列表、数组等。
具体聚合对象(Concrete Aggregate):实现聚合对象接口,创建具体迭代器对象,可以通过实现不同的聚合对象来提供不同方式的遍历。

在迭代器模式中,客户端通过获取聚合对象的迭代器,使用迭代器的方法遍历聚合对象中的元素,而无需暴露聚合对象的内部表示。这样可以提高系统的灵活性和可扩展性,同时也降低了聚合对象与迭代器之间的耦合度。

3、实现方式

3.1、案例引入

说到迭代器,大家应该很容易就想到在集合中的迭代器遍历集合的场景,这里我们就通过迭代器模式,自定义简单的集合和迭代器,模拟使用迭代器遍历集合的场景。

3.2、结构分析

在上述场景中,结构分别对应迭代器模式中的角色:

Container:对应迭代器模式中的抽象聚合类
ConcreteContainer:对应迭代器模式中的具体的聚合类
Iterator:对应迭代器模式中的抽象迭代器类;
ConcreteIterator:对应迭代器模式中的具体迭代器类;

3.3、具体实现

只在一个.cpp里实现,实际项目中建议分成多个文件 

#pragma once#include <iostream>
#include <unordered_map>
#include <vector>
#include <list>
#include <string>using namespace std;//1. 定义迭代器接口
class Iterator
{
public:// 下一个virtual int getNext() = 0;// 是否有下一个virtual bool hasMore() = 0;};//2. 定义容器接口
class Container
{
public:virtual Iterator* create_iterator() = 0;
};//3. 定义具体迭代器
class ConcreteIterator : public Iterator
{
public:// 构造函数,初始化成员变量ConcreteIterator(std::vector<int> data) : m_data(data), index(0) {}// 下一个virtual int getNext() {return m_data[index++];}// 是否有下一个virtual bool hasMore() {return index < m_data.size();}private:std::vector<int> m_data;int index;};// 4.定义具体容器
class ConcreteContainer : public Container
{
public:// 构造函数ConcreteContainer(std::vector<int> data) : m_data(data) {}// 创建迭代器virtual Iterator* create_iterator() {return new ConcreteIterator(m_data);}private:std::vector<int> m_data;};int main()
{//1. 创建容器std::vector<int> data = { 10, 20, 30, 40, 50 };Container* container = new ConcreteContainer(data);//2.创建迭代器Iterator* iterator = container->create_iterator();//3. 迭代器输出while (iterator->hasMore()) {std::cout << iterator->getNext() << " ";}// 清除delete iterator;delete container;iterator = nullptr;container = nullptr;return 0;
}
3.4 运行结果 

4.迭代器模式的优缺点
 

优点:

  •  符合单一职责原则。将遍历行为抽离成单独的类。
  •  符合开闭原则。添加新集合或者新迭代器,不改变原有代码
  • 代码复用性好。由于迭代器模式将遍历集合的代码封装到迭代器中,因此我们可以将同样的迭代器应用于不同的集合对象,从而减少了重复的代码;
  • 可以并行遍历同一集合。 因为每个迭代器对象都包含其自身的遍历状态。

缺点:

  • 若对聚合对象只需要进行简单的遍历行为,那使用迭代器模式有些大材小用。
  • 系统复杂性提高,类数量较多。

5、应用场景

  1. 在遍历集合元素时,不希望暴露集合内部的表示方式和数据结构,而是希望通过统一的接口进行操作。 迭代器模式使得我们可以将遍历行为封装在迭代器对象中,并把迭代器对象作为集合类的成员,从而达到这个目的;
  2. 当需要支持多种遍历方式时,可以使用迭代器模式。例如,在一个列表中,需要实现从前向后和从后向前两种遍历方式,使用迭代器模式非常方便地实现这样的需求;
  3. 需要提供一种通用的遍历机制,使得不同类型的集合对象都可以被遍历。由于迭代器模式将遍历过程封装在迭代器中,因此我们可以为每一种集合对象都提供一个对应的迭代器;
  4. 当需要对集合对象进行复杂的遍历操作时,可以使用迭代器模式。例如,有些集合对象可能需要在遍历过程中进行筛选、排序等处理,这些逻辑可以在迭代器中完成,从而使得客户端代码保持简洁。

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

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

相关文章

STM32F4 IAP跳转APP问题及STM32基于Ymodem协议IAP升级笔记

STM32F4 IAP 跳转 APP问题 ST官网IAP例程Chapter1 STM32F4 IAP 跳转 APP问题1. 概念2. 程序2.1 Bootloader 程序 问题现象2.2. APP程序 3. 代码4. 其他问题 Chapter2 STM32-IAP基本原理及应用 | ICP、IAP程序下载流程 | 程序执行流程 | 配置IAP到STM32F4xxxChapter3 STM32基于Y…

SQLite数据库在Linux系统上的使用

SQLite是一个轻量级的数据库解决方案&#xff0c;它是一个嵌入式的数据库管理系统。SQLite的特点是无需独立的服务器进程&#xff0c;可以直接嵌入到使用它的应用程序中。由于其配置简单、支持跨平台、服务器零管理&#xff0c;以及不需要复杂的设置和操作&#xff0c;SQLite非…

python如何输入多行

Python中的Input()函数在输入时&#xff0c;遇到回车符&#xff0c;那么一次输入就结束了。这不能满足输入多行文本并且行数也不确定的情形&#xff0c;当然输入空行也是允许的。 方法1&#xff1a;利用异常处理机制实现 lines[] while True:try:lines.append(input())except:…

达梦数据库清理归档日志的方法

达梦数据库清理归档日志的方法 在达梦数据库&#xff08;DM数据库&#xff09;中&#xff0c;归档日志文件是数据库运行过程中产生的&#xff0c;用于记录所有对数据库修改的详细信息。这些日志对于数据库的恢复非常关键&#xff0c;尤其是在进行灾难恢复或数据恢复时。然而&a…

关于Linux下的进程等待(进程篇)

目录 为什么存在进程等待&#xff1f;进程等待是在做什么&#xff1f; 怎样去执行进程等待&#xff1f; status options 为什么存在进程等待&#xff1f;进程等待是在做什么&#xff1f; 代码示例&#xff1a;模仿僵尸进程 #include <stdio.h> #include <unistd.…

xss跨站脚本攻击笔记

1 XSS跨站脚本攻击 1.1 xss跨站脚本攻击介绍 跨站脚本攻击英文全称为(Cross site Script)缩写为CSS&#xff0c;但是为了和层叠样式表(CascadingStyle Sheet)CSS区分开来&#xff0c;所以在安全领域跨站脚本攻击叫做XSS 1.2 xss跨战脚本攻击分类 第一种类型:反射型XSS 反射…

java数据结构与算法刷题-----LeetCode684. 冗余连接

java数据结构与算法刷题目录&#xff08;剑指Offer、LeetCode、ACM&#xff09;-----主目录-----持续更新(进不去说明我没写完)&#xff1a;https://blog.csdn.net/grd_java/article/details/123063846 文章目录 并查集 并查集 解题思路&#xff1a;时间复杂度O( n ∗ l o g 2…

ThinkPHP审计(2) Thinkphp反序列化链5.1.X原理分析从0编写POC

ThinkPHP审计(2) Thinkphp反序列化链子5.1.X原理分析&从0编写POC 文章目录 ThinkPHP审计(2) Thinkphp反序列化链子5.1.X原理分析&从0编写POC动态调试环境配置Thinkphp反序列化链5.1.X原理分析一.实现任意文件删除二.实现任意命令执行真正的难点 Thinkphp反序列化链5.1.…

JVM规范中的运行时数据区

✅作者简介&#xff1a;大家好&#xff0c;我是Leo&#xff0c;热爱Java后端开发者&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f34e;个人主页&#xff1a;Leo的博客 &#x1f49e;当前专栏&#xff1a;每天一个知识点 ✨特色专栏&#xff1a…

SpringBoot 集成H2数据库,启动执行sql, 中文乱码

目录 H2数据库介绍 SpringBoot版本&#xff1a;SpringBoot 2.1.12.RELEASE 快速集成H2&#xff0c;maven依赖 快速集成H2&#xff0c;数据源及关键参数配置 spring.datasource.schema参数&#xff08;建表SQL脚本&#xff09; spring.datasource.data参数&#xff08;更新、…

Qt5 编译 Qt Creator 源码中的 linguist 模块

文章目录 下载 Qt Creator 源码手动翻译多语言自动翻译多语言 下载 Qt Creator 源码 Github: https://github.com/qt/qttools 笔记打算用 Qt 5.12.12 来编译 qt creator-linguist 所以笔者下载的是 tag - 5.12.12 &#xff0c;解压后如下&#xff0c;先删除多余的文件&#xf…

【Vue】Vue3中的OptionsAPI与CompositionAPI

文章目录 OptionsAPICompositionAPI对比总结 OptionsAPI 中文名:选项式API通过定义methods,computed,watch,data等属性方法&#xff0c;处理页面逻辑。以下是OptionsAPI代码结构 实例代码: <script lang"ts">// js或者tsimport { defineComponent } from vu…

【学习】软件测试需求分析要从哪些方面入手

软件测试需求分析是软件测试过程中非常重要的一个环节&#xff0c;它是为了明确软件测试的目标、范围、资源和时间等要素&#xff0c;以确保软件测试的有效性和全面性。本文将从以下几个方面对软件测试需求分析进行详细的阐述&#xff1a; 一、软件测试目标 软件测试目标是指…

读所罗门的密码笔记16_直通心智

1. 直通心智 1.1. 如今&#xff0c;科学家已经可以诱发触觉、压觉、痛觉和大约250种其他感觉 1.1.1. DARPA支持的触觉技术第一次让一位受伤的人能够用假肢和手指感知到被触碰的物体 1.1.2. 可以建立人工系统&#xff0c;来替换和弥补受损大脑的部分区域 1.1.3. 神经科学家能…

Nginx日志格式化和追踪

背景 Nginx是一款功能强大的Web服务器&#xff0c;对于网络环境中的日志记录和配置至关重要。定制化Nginx日志格式可以帮助管理员更好地监控服务器性能、分析用户行为并做出相应优化。在本文中&#xff0c;我们将深入探讨Nginx日志格式的高级定制化策略&#xff0c;包括理解基…

词频统计程序

使用Hadoop MapReduce处理文本文件&#xff0c;Mapper负责将文本分割为单词&#xff0c;然后Reducer对每个单词进行计数&#xff0c;最后将结果写入输出文件。 // 定义WordCount公共类 public class WordCount {// 主入口方法&#xff0c;处理命令行参数public static void m…

循环神经网络RNN

循环神经网络RNN是一种人工神经网络&#xff0c;旨在处理时间序列、语音和自然语言等序列数据。将RNN 想象成传送带&#xff0c;一次处理一个元素的信息&#xff0c;从而 "记住 "前一个元素的信息&#xff0c;对下一个元素做出预测。   想象一下&#xff0c;我们有…

【多线程】Thread的常见属性 | 终止线程 | 等待线程 | 休眠线程 | 线程安全

文章目录 一、Thread的方法Thread的常见属性后台线程&#xff08;守护线程&#xff09;设置后台线程是否存活 启动线程终止\打断一个线程1.创建标志位2.调用 interrupt() 方法 等待一个线程 join()t.join&#xff08;&#xff09;的工作过程&#xff1a; 休眠一个进程sleep 二、…

ppt从零基础到高手【办公】

第一章&#xff1a;文字排版篇01演示文稿内容基密02文字操作规范03文字排版处理04复习&作业解析第二章&#xff1a;图形图片图表篇05图形化表达06图片艺术化07轻松玩转图表08高效工具&母版统一管理09复习&作业解析10轻松一刻-文字图形小技巧速学第三章&#xff1a;…

vue模版字符串解析成vue模版对象

模版字符串 this.code <template><div style"width:100% ; height: 100% ;">{{resultData[0].name}}</div> </template> <script> export default {data() {return {resultData: [{ name: 图幅, value: 20 },]}},mounted(){},method…