瑞_23种设计模式_迭代器模式

文章目录

    • 1 迭代器模式(Iterator Pattern)★★★
      • 1.1 介绍
      • 1.2 概述
      • 1.3 迭代器模式的结构
      • 1.4 中介者模式的优缺点
      • 1.5 中介者模式的使用场景
    • 2 案例一
      • 2.1 需求
      • 2.2 代码实现
    • 3 案例二
      • 3.1 需求
      • 3.2 代码实现
    • 4 JDK源码解析

🙊 前言:本文章为瑞_系列专栏之《23种设计模式》的迭代器模式篇。本文中的部分图和概念等资料,来源于博主学习设计模式的相关网站《菜鸟教程 | 设计模式》和《黑马程序员Java设计模式详解》,特此注明。本文中涉及到的软件设计模式的概念、背景、优点、分类、以及UML图的基本知识和设计模式的6大法则等知识,建议阅读 《瑞_23种设计模式_概述》

本系列 - 设计模式 - 链接:《瑞_23种设计模式_概述》

⬇️本系列 - 创建型模式 - 链接🔗

  单例模式:《瑞_23种设计模式_单例模式》
  工厂模式:《瑞_23种设计模式_工厂模式》
  原型模式:《瑞_23种设计模式_原型模式》
抽象工厂模式:《瑞_23种设计模式_抽象工厂模式》
 建造者模式:《瑞_23种设计模式_建造者模式》

⬇️本系列 - 结构型模式 - 链接🔗

  代理模式:《瑞_23种设计模式_代理模式》
 适配器模式:《瑞_23种设计模式_适配器模式》
 装饰者模式:《瑞_23种设计模式_装饰者模式》
  桥接模式:《瑞_23种设计模式_桥接模式》
  外观模式:《瑞_23种设计模式_外观模式》
  组合模式:《瑞_23种设计模式_组合模式》
  享元模式:《瑞_23种设计模式_享元模式》

⬇️本系列 - 行为型模式 - 链接🔗

模板方法模式:《瑞_23种设计模式_模板方法模式》
  策略模式:《瑞_23种设计模式_策略模式》
  命令模式:《瑞_23种设计模式_命令模式》
 职责链模式:《瑞_23种设计模式_职责链模式》
  状态模式:《瑞_23种设计模式_状态模式》
 观察者模式:《瑞_23种设计模式_观察者模式》
 中介者模式:《瑞_23种设计模式_中介者模式》
 迭代器模式:《后续更新》
 访问者模式:《后续更新》
 备忘录模式:《后续更新》
 解释器模式:《后续更新》

在这里插入图片描述

1 迭代器模式(Iterator Pattern)★★★

瑞:在Java中,想使用迭代器模式的话,只要让我们自己定义的容器类实现java.util.Iterable并实现其中的iterator()方法使其返回一个 java.util.Iterator 的实现类就可以了。

  迭代器模式(Iterator Pattern)是 Java 和 .Net 编程环境中非常常用的设计模式。这种模式用于顺序访问集合对象的元素,不需要知道集合对象的底层表示。迭代器模式属于行为型模式。

  瑞:行为型模式用于描述程序在运行时复杂的流程控制,即描述多个类或对象之间怎样相互协作共同完成单个对象都无法单独完成的任务,它涉及算法与对象间职责的分配。
  瑞:行为型模式分为类行为模式对象行为模式,前者采用继承机制来在类间分派行为,后者采用组合或聚合在对象间分配行为。由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象行为模式比类行为模式具有更大的灵活性

迭代器模式属于:对象行为模式

1.1 介绍

  • 意图:提供一种方法顺序访问一个聚合对象中各个元素, 而又无须暴露该对象的内部表示。

  • 主要解决:遍历一个聚合对象。

  • 何时使用:多个类相互耦合,形成了网状结构。

  • 如何解决:把在元素之间游走的责任交给迭代器,而不是聚合对象。

  • 关键代码:定义接口:hasNext, next。

  • 应用实例
      1️⃣ JAVA 中的 iterator

  • 优点
      1️⃣ 它支持以不同的方式遍历一个聚合对象。
      2️⃣ 迭代器简化了聚合类。
      3️⃣ 在同一个聚合上可以有多个遍历。
      4️⃣ 在迭代器模式中,增加新的聚合类和迭代器类都很方便,无须修改原有代码。

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

  • 使用场景
      1️⃣ 访问一个聚合对象的内容而无须暴露它的内部表示。
      2️⃣ 需要为聚合对象提供多种遍历方式。
      3️⃣ 为遍历不同的聚合结构提供一个统一的接口。

  • 注意事项
      1️⃣ 迭代器模式就是分离了集合对象的遍历行为,抽象出一个迭代器类来负责,这样既可以做到不暴露集合的内部结构,又可让外部代码透明地访问集合内部的数据。

1.2 概述

定义:提供一个对象来顺序访问聚合对象中的一系列数据,而不暴露聚合对象的内部表示。

  迭代器模式是一种强大的设计模式,它通过将遍历逻辑封装在迭代器对象中,实现了对集合对象的统一访问和操作,从而简化了客户端代码并提高了代码的可读性和可维护性。

  在Java中,迭代器模式得到了广泛的应用。Java集合框架(Collections Framework)中的Iterator接口就是迭代器模式的一个典型实现。通过实现Iterator接口,Java集合类(如ArrayList、LinkedList等)提供了统一的遍历方式,使得客户端可以方便地访问和操作集合中的元素。

1.3 迭代器模式的结构

  • 迭代器模式主要包含以下角色:
      1️⃣ 抽象聚合(Aggregate)角色:定义存储、添加、删除聚合元素以及创建迭代器对象的接口。
      2️⃣ 具体聚合(ConcreteAggregate)角色:实现抽象聚合类,返回一个具体迭代器的实例。
      3️⃣ 抽象迭代器(Iterator)角色:定义访问和遍历聚合元素的接口,通常包含 hasNext()、next() 等方法。
      4️⃣ 具体迭代器(Concretelterator)角色:实现抽象迭代器接口中所定义的方法,完成对聚合对象的遍历,记录遍历的当前位置。

1.4 中介者模式的优缺点

优点

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

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

  • 在迭代器模式中,由于引入了抽象层,增加新的聚合类和迭代器类都很方便,无须修改原有代码,满足 “开闭原则” 的要求。

缺点

  • 增加了类的个数,这在一定程度上增加了系统的复杂性。

1.5 中介者模式的使用场景

  • 当需要为聚合对象提供多种遍历方式时。
  • 当需要为遍历不同的聚合结构提供一个统一的接口时。
  • 当访问一个聚合对象的内容而无须暴露其内部细节的表示时。



2 案例一

【案例】自定义迭代器

2.1 需求

  定义一个可以存储学生对象的容器对象,将遍历该容器的功能交由迭代器实现。

  类图如下:

在这里插入图片描述

2.2 代码实现

  定义迭代器接口,声明hasNext、next方法

抽象迭代器角色接口(接口)
/*** 抽象迭代器角色接口** @author LiaoYuXing-Ray**/
public interface StudentIterator {// 判断是否还有元素boolean hasNext();// 获取下一个元素Student next();
}

  定义具体的迭代器类,重写所有的抽象方法

具体迭代器角色类(类)
import java.util.List;/*** 具体迭代器角色类** @author LiaoYuXing-Ray**/
public class StudentIteratorImpl implements StudentIterator {private final List<Student> list;private int position = 0; // 用来记录遍历时的位置public StudentIteratorImpl(List<Student> list) {this.list = list;}public boolean hasNext() {return position < list.size();}public Student next() {// 从集合中获取指定位置的元素Student currentStudent = list.get(position);position++;return currentStudent;}
}

  定义抽象容器类,包含添加元素,删除元素,获取迭代器对象的方法

抽象聚合角色接口(接口)
/*** 抽象聚合角色接口** @author LiaoYuXing-Ray**/
public interface StudentAggregate {// 添加学生功能void addStudent(Student stu);// 删除学生功能void removeStudent(Student stu);// 获取迭代器对象功能StudentIterator getStudentIterator();
}

  定义具体的容器类,重写所有的方法

具体的容器类(类)

import java.util.ArrayList;
import java.util.List;/*** 具体的容器类** @author LiaoYuXing-Ray**/
public class StudentAggregateImpl implements StudentAggregate {private final List<Student> list = new ArrayList<Student>();public void addStudent(Student stu) {list.add(stu);}public void removeStudent(Student stu) {list.remove(stu);}// 获取迭代器对象public StudentIterator getStudentIterator() {return new StudentIteratorImpl(list);}
}

  迭代器元素类

学生类(类)
/*** 学生类** @author LiaoYuXing-Ray**/
public class Student {private String name;private String number;@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", number='" + number + '\'' +'}';}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getNumber() {return number;}public void setNumber(String number) {this.number = number;}public Student(String name, String number) {this.name = name;this.number = number;}public Student() {}
}
测试类
/*** 测试类** @author LiaoYuXing-Ray**/
public class Client {public static void main(String[] args) {// 创建聚合对象StudentAggregateImpl aggregate = new StudentAggregateImpl();// 添加元素aggregate.addStudent(new Student("张三","001"));aggregate.addStudent(new Student("李四","002"));aggregate.addStudent(new Student("王五","003"));aggregate.addStudent(new Student("赵六","004"));// 遍历聚合对象// 1.获取迭代器对象StudentIterator iterator = aggregate.getStudentIterator();// 2.遍历while(iterator.hasNext()) {// 3.获取元素Student student = iterator.next();System.out.println(student.toString());}}
}

  代码运行结果如下:

	Student{name='张三', number='001'}Student{name='李四', number='002'}Student{name='王五', number='003'}Student{name='赵六', number='004'}

3 案例二

本案例为菜鸟教程中的案例

3.1 需求

  我们将创建一个叙述导航方法的 Iterator 接口和一个返回迭代器的 Container 接口。实现了 Container 接口的实体类将负责实现 Iterator 接口。

  IteratorPatternDemo,我们的演示类使用实体类 NamesRepository 来打印 NamesRepository 中存储为集合的 Names。

在这里插入图片描述

3.2 代码实现

步骤 1

  创建接口

Iterator.java
public interface Iterator {public boolean hasNext();public Object next();
}
Container.java
public interface Container {public Iterator getIterator();
}

步骤 2

  创建实现了 Container 接口的实体类。该类有实现了 Iterator 接口的内部类 NameIterator。

NameRepository.java
public class NameRepository implements Container {public String[] names = {"Robert" , "John" ,"Julie" , "Lora"};@Overridepublic Iterator getIterator() {return new NameIterator();}private class NameIterator implements Iterator {int index;@Overridepublic boolean hasNext() {if(index < names.length){return true;}return false;}@Overridepublic Object next() {if(this.hasNext()){return names[index++];}return null;}     }
}

步骤 3

  使用 NameRepository 来获取迭代器,并打印名字。

IteratorPatternDemo.java
public class IteratorPatternDemo {public static void main(String[] args) {NameRepository namesRepository = new NameRepository();for(Iterator iter = namesRepository.getIterator(); iter.hasNext();){String name = (String)iter.next();System.out.println("Name : " + name);}  }
}

步骤 4

  执行程序,输出结果:

	Name : RobertName : JohnName : JulieName : Lora



4 JDK源码解析

  迭代器模式在JAVA的很多集合类中被广泛应用,接下来看看JAVA源码中是如何使用迭代器模式的。

List<String> list = new ArrayList<>();
Iterator<String> iterator = list.iterator(); //list.iterator()方法返回的肯定是Iterator接口的子实现类对象
while (iterator.hasNext()) {System.out.println(iterator.next());
}

  看完这段代码是不是很熟悉,与我们案例一的代码实现基本类似。单列集合都使用到了迭代器,我们以ArrayList举例来说明

  • List:抽象聚合类
  • ArrayList:具体的聚合类
  • Iterator:抽象迭代器
  • list.iterator():返回的是实现了 Iterator 接口的具体迭代器对象

  具体看看ArrayList的代码实现

public class ArrayList<E> extends AbstractList<E>implements List<E>, RandomAccess, Cloneable, java.io.Serializable {public Iterator<E> iterator() {return new Itr();}private class Itr implements Iterator<E> {int cursor;       // 下一个要返回元素的索引int lastRet = -1; // 上一个返回元素的索引int expectedModCount = modCount;Itr() {}//判断是否还有元素public boolean hasNext() {return cursor != size;}//获取下一个元素public E next() {checkForComodification();int i = cursor;if (i >= size)throw new NoSuchElementException();Object[] elementData = ArrayList.this.elementData;if (i >= elementData.length)throw new ConcurrentModificationException();cursor = i + 1;return (E) elementData[lastRet = i];}...
}

  这部分代码大致就是在 iterator 方法中返回了一个实例化的 Iterator 对象。Itr是一个内部类,它实现了 Iterator 接口并重写了其中的抽象方法。

所以当我们在使用JAVA开发的时候,想使用迭代器模式的话,只要让我们自己定义的容器类实现java.util.Iterable并实现其中的iterator()方法使其返回一个 java.util.Iterator 的实现类就可以了




本文是博主的粗浅理解,可能存在一些错误或不完善之处,如有遗漏或错误欢迎各位补充,谢谢

  如果觉得这篇文章对您有所帮助的话,请动动小手点波关注💗,你的点赞👍收藏⭐️转发🔗评论📝都是对博主最好的支持~


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

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

相关文章

【论文笔记】Text2QR

论文&#xff1a;Text2QR: Harmonizing Aesthetic Customization and Scanning Robustness for Text-Guided QR Code Generation Abstract 二维码通常包含很多信息但看起来并不美观。stable diffusion的出现让平衡扫描鲁棒性和美观变为可能。 为了保证美观二维码的稳定生成&a…

6款Mac垃圾清理软件横评 Mac电脑清理软件哪个好 cleanmymac评测

鉴于苹果笔记本昂贵的硬盘价格&#xff0c;导致我们不得不定期清理自己的硬盘空间&#xff0c;释放给真正有用的各种程序等。 即便我们把程序安装到外置硬盘&#xff0c;但是程序运行时的缓存&#xff0c;仍然是在内置的硬盘中。 今天就让我们对比看看&#xff0c;目前市面上…

从 Redis 开源协议变更到 ES 国产化:一次技术自主的机遇

引言 近日&#xff0c;Redis Labs 宣布其主导的开源项目 Redis 将采用双重源代码可用许可证&#xff08;RSALv2&#xff09;和服务器端公共许可证&#xff08;SSPLv1&#xff09;。这一重大决策标志着 Redis 从传统的 BSD 许可证向更加严格的控制权转变&#xff0c;同时也引发…

物流管理系统|基于Springboot的物流管理系统设计与实现(源码+数据库+文档)

物流管理系统目录 目录 基于Springboot的物流管理系统设计与实现 一、前言 二、系统功能设计 三、系统实现 1、管理员和管理员功能实现 &#xff08;1&#xff09;用户管理 &#xff08;2&#xff09;公告信息管理 &#xff08;3&#xff09;物流信息管理 &#xff08;…

智慧安防监控EasyCVR视频调阅和设备录像回看无法自动播放的原因排查与解决

智慧安防监控EasyCVR视频管理平台能在复杂的网络环境中&#xff0c;将前端设备统一集中接入与汇聚管理。国标GB28181协议视频监控/视频汇聚EasyCVR平台可以提供实时远程视频监控、视频录像、录像回放与存储、告警、语音对讲、云台控制、平台级联、磁盘阵列存储、视频集中存储、…

【面试八股总结】超文本传输协议HTTP(一)

一、 什么是HTTP协议&#xff1f; HTTP是超文本传输协议 HyperText Transfer Protocol 特性&#xff1a; 简单、灵活、易于扩展无状态&#xff1a;服务器不会记忆HTTP状态不安全&#xff1a;通信使用明文&#xff0c;不验证通信方身份&#xff0c;无法的证明报文的完整性&…

Kubernetes kafka系列 | Strimzi 部署kafka-bridge

Strimzi kafka集群部署直通车 一、kafka bridge 介绍 Kafka Bridge 是 Apache Kafka 生态系统中的一个工具或组件&#xff0c;用于实现 Kafka 与其他系统或协议之间的通信或集成。Kafka 本身是一个分布式事件流平台&#xff0c;广泛用于构建实时数据流水线和流式应用程序。然而…

四川易点慧电子商务抖音小店:安全靠谱,购物新体验

随着互联网的飞速发展&#xff0c;电子商务已经成为人们日常生活中不可或缺的一部分。四川易点慧电子商务有限公司&#xff0c;作为一家专注于抖音小店的电商平台&#xff0c;以其安全靠谱的特性&#xff0c;赢得了广大消费者的信赖和喜爱。 一、平台背景与实力 四川易点慧电子…

iPhone设备中如何导出和分享应用程序崩溃日志的实用方法

​ 目录 如何在iPhone设备中查看崩溃日志 摘要 引言 导致iPhone设备崩溃的主要原因是什么&#xff1f; 使用克魔助手查看iPhone设备中的崩溃日志 奔溃日志分析 总结 摘要 本文介绍了如何在iPhone设备中查看崩溃日志&#xff0c;以便调查崩溃的原因。我们将展示三种不同的…

MVC与三层架构理解

1. JSP的发展 早期只有Servlet&#xff0c;只能使用response输出标签数据&#xff0c;非常麻烦后来。JSP的出现&#xff0c;简化了 Servlet的开发。但是过度的使用JSP&#xff0c;在JSP中写大量的java代码&#xff0c;又前端的页面&#xff0c;造成难以维护&#xff0c;难于分…

Excel制作甘特图

使用Excel表格制作甘特图&#xff0c;可根据任务开始时间和结束时间自动计算工时&#xff0c;并自动用指定颜色填充横道图。 1.新建Excel文档&#xff0c;先设置项目基本信息&#xff0c;包括表格名称&#xff0c;这里设置为“**项目甘特图”&#xff1b;然后添加任务序号列&a…

【软件工程导论】——面向对象与UML(学习笔记)

&#x1f4d6; 前言&#xff1a;面向对象是以问题空间中出现的物体为中心进行模型化的一种技术。建立模型是软件工程中最常使用的技术之一。无论软件分析或软件设计&#xff0c;都需要建立模型。UML 就是OO 软件工程使用的统一建模语言。它是一种图形化的语言&#xff0c;主要用…

3D DRAM在2025年来袭

4月1日消息&#xff0c;据半导体工程报道&#xff0c;在行业大会Memcon 2024上&#xff0c;三星电子宣布其计划成为首家在2025年后步入3D DRAM内存时代的行业领军者。随着DRAM内存行业在本十年后期将线宽压缩至低于10纳米&#xff0c;现有的设计解决方案在如此精细的尺度上难以…

HarmonyOS 应用开发之Actor并发模型对比内存共享并发模型

内存共享并发模型指多线程同时执行复数任务&#xff0c;这些线程依赖同一内存并且都有权限访问&#xff0c;线程访问内存前需要抢占并锁定内存的使用权&#xff0c;没有抢占到内存的线程需要等待其他线程释放使用权再执行。 Actor并发模型每一个线程都是一个独立Actor&#xf…

Cisco交换机安全配置

Cisco交换机安全配置 前提 我们以下命令一般都要先进入Config模式 S1> enable S1# conf t S1(config)#端口安全保护 禁用未使用的端口 以关闭fa0/1到fa0/24的端口为例 S1(config)# interface range fa0/1-24 S1(config-if-range)# shutdown缓解MAC地址表攻击 防止CAM…

sql注入---Union注入

文章目录 前言一、pandas是什么&#xff1f;二、使用步骤 1.引入库2.读入数据总结 学习目标 了解union注入过程中用到的关键数据库&#xff0c;数据表&#xff0c;数据列sql查询中group_concat的作用使用union注入拿到靶机中数据库里的所有用户名和密码 一. 获得数据库表名和列…

酷开系统 | 酷开科技打造全流程全自动化运营链路

近日&#xff0c;QuestMobile发布的《2023年全景生态流量半年报告》数据显示&#xff0c;随着营销场景边界的拓展&#xff0c;越来越多的品牌方开始将阵地由移动端转移到大屏端。OTT及智能硬件营销占中国互联网营销市场规模比例已经从2020年的3.8%升至2022年的7.6%。随着人口红…

【JavaWeb】Day30.SpringBootWeb请求响应——响应

响应 HTTL协议的交互方式&#xff1a;请求响应模式&#xff08;有请求就有响应&#xff09;那么Controller程序&#xff0c;除了接收请求外&#xff0c;还可以进行响应。 1.ResponseBody 在我们前面所编写的controller方法中&#xff0c;都已经设置了响应数据。 controller方…

【C语言进阶】- 内存函数

内存函数 1.1 内存函数的使用1.2 memcpy函数的使用1.3 memcpy函数的模拟实现2.1 memmove函数的使用2.2 memmove函数的模拟实现2.3 memcmp函数的使用2.4 memset函数的使用 1.1 内存函数的使用 内存函数就是对内存中的数据进行操作的函数 1.2 memcpy函数的使用 void* memcpy ( …

Docker容器与Serverless的融合:探索《2023腾讯云容器和函数计算技术实践精选集》中的云原生创新案例

Docker容器与Serverless的融合&#xff1a;探索《2023腾讯云容器和函数计算技术实践精选集》中的云原生创新案例 文章目录 Docker容器与Serverless的融合&#xff1a;探索《2023腾讯云容器和函数计算技术实践精选集》中的云原生创新案例一、引言二、《2023腾讯云容器和函数计算…