Java设计模式之行为型-迭代器模式(UML类图+案例分析)

目录

一、基础概念

二、UML类图

三、角色设计

四、案例分析

五、总结


一、基础概念

迭代器模式是一种常用的设计模式,它主要用于遍历集合对象,提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露该对象的内部表示。

举个简单的比喻,聚合对象像一个存放苹果的篮子,迭代器就像篮子边上的搬运工,专门负责把苹果一个一个取出来。客户端只需要找到搬运工,然后不停地让他取出苹果就可以了,而不需要关心篮子里面是怎么存放的。这样既方便客户端使用,也屏蔽了聚合对象内部的复杂性!

二、UML类图

三、角色设计

角色描述
抽象聚合角色定义存创建、添加、获取等迭代器对象的接口
具体聚合角色抽象聚合角色的实现类,返回一个具体迭代器实例
抽象迭代器角色定义访问和遍历聚合元素的接口,通常包裹hashNext()和next()方法
具体迭代器角色实现抽象迭代器接口中所定义的方法,完成聚合对象的遍历,记录遍历的当前为止
客户端角色用于使用迭代器遍历聚合对象

四、案例分析

用迭代器模式模拟一个学生管理系统,主要内容如下:

1、定义Student类,表示学生信息。

2、定义StudentAggregate接口,作为学生集合的抽象接口。

3、实现StudentAggregateImpl类,具体的学生集合,使用List存储Student。

4、定义Iterator接口,规定迭代器的通用方法。

5、实现StudentIterator类,具体的学生迭代器。

6、在客户端代码中,通过迭代器遍历StudentAggregateImpl中的学生集合。

通过迭代器模式实现对学生集合的遍历,同时隐藏学生集合的具体实现细节,示例代码如下:

定义学生类:

public class Student {private String name;private int age;public Student(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public int getAge() {return age;}
}

学生集合抽象聚合类:


public interface StudentAggregate {public Iterator createIterator();public int getNumberOfStudents();public Student getStudent(int index);public void addStudent(Student student);}

学生集合具体聚合角色:

import java.util.ArrayList;
import java.util.List;public class StudentAggregateImpl implements StudentAggregate{private List<Student> students;public StudentAggregateImpl() {students = new ArrayList<>();}@Overridepublic Iterator createIterator() {return new StudentIterator(this);}  @Overridepublic int getNumberOfStudents() {return students.size();}@Overridepublic Student getStudent(int index) {return students.get(index);}@Overridepublic void addStudent(Student student) {students.add(student);}
}

 抽象迭代器角色:

public interface Iterator {public boolean hasNext();public Student next();}

学生具体迭代器角色:

public class StudentIterator implements Iterator {private StudentAggregate studentAggregate;private int index;public StudentIterator(StudentAggregate studentAggregate) {this.studentAggregate = studentAggregate;}@Overridepublic boolean hasNext() {return (index < studentAggregate.getNumberOfStudents());}@Overridepublic Student next() {return studentAggregate.getStudent(index++);}}

客户端:

public class Client {public static void main(String[] args) {//使用示例StudentAggregate students = new StudentAggregateImpl();// 添加学生Student john = new Student("John", 18);Student mike = new Student("Mike", 18);students.addStudent(john);students.addStudent(mike);Iterator iterator = students.createIterator();while(iterator.hasNext()) {Student student = iterator.next();System.out.println(student.getName());}}
}

运行结果如下:

这个迭代器模式在学生管理示例中的执行逻辑过程: 

1、定义Student类,用于表示学生信息。

2、定义StudentAggregate接口,作为抽象学生集合类,声明管理学生的通用方法。

3、实现StudentAggregateImpl类,具体的学生集合,使用List存储Student对象。

4、定义Iterator接口,规定迭代器的通用方法。

5、实现StudentIterator类,具体的学生迭代器,持有对StudentAggregate的引用。

6、创建StudentAggregateImpl对象students,表示具体的学生集合。

7、调用students的addStudent()方法,向集合中添加学生。

8、调用students的createIterator()方法,获取迭代器对象。

9、使用迭代器的hasNext()和next()方法遍历students集合,访问其中的学生对象。

10、在整个过程中,客户端代码都只与Iterator接口发生依赖,而不需了解学生集合的具体实现/

这样通过迭代器模式可以实现学生集合的遍历,同时也达到了对访问学生集合的控制和集合内部表示的封装。 

五、总结

优点:

1隔离了集合对象的遍历行为,抽象出一个迭代器类来负责迭代元素。

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

3迭代器简化了聚合类。客户端如果需要遍历聚合对象,只需要初始化一个迭代器,不需要知道聚合对象内部的具体实现。

4在同一个聚合类中可以定义多个遍历方式,通过不同的迭代器来实现。

5符合单一职责原则。

6实现了集合类的常用遍历算法,容易扩展和维护。

缺点:

1、增加了类的个数,代码复杂度会增加,需要维护更多的代码。

2、多态性能损耗。遍历时需要进行多次虚函数调用,遍历效率降低。

3、遍历算法复用性差。每次遍历都需要创建新的迭代器实例,无法重用已定义好的遍历算法。

应用场景:

1、访问一个聚合对象的内容而无需暴露它的内部表示。

2、为遍历不同的集合结构提供一个统一的接口(即支持多态迭代)。

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

4、分离集合对象的遍历行为到一个独立的迭代器类中。

符合的设计原则:

1、单一职责原则(Single Responsibility Principle)

迭代器模式将集合对象的遍历行为抽象到迭代器类中,集合类只负责存储,迭代器类只负责遍历。二者职责区分明确,符合单一职责原则。

2、开闭原则(Open Closed Principle)

可以在不修改集合类的情况下,定义新的迭代器类,满足扩展需求。增强了系统的可扩展性。

3、依赖倒转原则(Dependency Inversion Principle)

迭代器模式中,集合类和客户端都依赖于抽象迭代器接口,而不是依赖于具体迭代器类,倒转了依赖关系。

4、组合复用原则(Composite Reuse Principle)

客户端可以统一使用迭代器接口遍历不同的集合类,复用迭代器提供的遍历功能。

5、里氏替换原则(Liskov Substitution Principle)

迭代器模式中,每个迭代器类都可以通过继承迭代器接口,替换基类迭代器角色。

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

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

相关文章

5分钟给你破解这套10万赞的生产教程,访谈乔布斯的AI对话数字人视频是怎么做的

本期是赤辰第16期AI项目拆解栏目&#xff1b; 底部准备了7月粉丝福利&#xff0c;看完可以领取&#xff1b; 上周给粉丝们讲解AI动图说话月涨粉20万的案例并给出保姆式教程&#xff0c;粉丝反馈很热烈&#xff0c;都觉得AI强大&#xff0c;有些学员给自己账号做视频&#xff…

大数据与视频技术的融合趋势将带来怎样的场景应用?

视频技术和AI技术的融合是一种新兴的技术趋势&#xff0c;它将改变视频行业的运作方式。视频技术和AI技术的融合主要包括以下几个方面&#xff1a; 1&#xff09;人脸识别技术 人脸识别技术是AI技术的一个重要应用场景。它可以通过对视频中的人脸进行识别和分析&#xff0c;实…

3.9 Bootstrap 分页

文章目录 Bootstrap 分页分页&#xff08;Pagination&#xff09;默认的分页分页的状态分页的大小 翻页&#xff08;Pager&#xff09;默认的翻页对齐的链接翻页的状态 分页 Bootstrap 分页 本章将讲解 Bootstrap 支持的分页特性。分页&#xff08;Pagination&#xff09;&…

Unity平台如何实现RTSP转RTMP推送?

技术背景 Unity平台下&#xff0c;RTSP、RTMP播放和RTMP推送&#xff0c;甚至包括轻量级RTSP服务这块都不再赘述&#xff0c;今天探讨的一位开发者提到的问题&#xff0c;如果在Unity下&#xff0c;实现RTSP播放的同时&#xff0c;随时转RTMP推送出去&#xff1f; RTSP转RTMP…

浙大数据结构第四周之04-树6 Complete Binary Search Tree

题目详情&#xff1a; A Binary Search Tree (BST) is recursively defined as a binary tree which has the following properties: The left subtree of a node contains only nodes with keys less than the nodes key.The right subtree of a node contains only nodes w…

[javascript核心-08] V8 内存管理机制及性能优化

V8 内存管理 V8 本身也是程序&#xff0c;它本身也会申请内存&#xff0c;它申请的内存称为常驻内存&#xff0c;而它又将内存分为堆和栈 栈内存 栈内存介绍 栈用于存放JS 中的基本类型和引用类型指针栈空间是连续的&#xff0c;增加删除只需要移动指针&#xff0c;操作速度…

代码随香录day21

235. 二叉搜索树的最近公共祖先 本题思路&#xff1a; 还是要利用二叉搜索树的特性&#xff0c;中序遍历为有序数组。如果pq两个节点都小于root&#xff0c;那么最近公共祖肯定是在他的左子树&#xff0c;如果都大于那么&#xff0c;肯定就在右子树。然后直接return root 代码…

Linux Ubuntu安装RabbitMQ服务

文章目录 前言1.安装erlang 语言2.安装rabbitMQ3. 内网穿透3.1 安装cpolar内网穿透(支持一键自动安装脚本)3.2 创建HTTP隧道 4. 公网远程连接5.固定公网TCP地址5.1 保留一个固定的公网TCP端口地址5.2 配置固定公网TCP端口地址 前言 RabbitMQ是一个在 AMQP(高级消息队列协议)基…

【前端知识】React 基础巩固(二十七)——Fragment

React 基础巩固(二十七)——Fragment Fragment Fragment 允许将子列表分组&#xff0c;而无需向 DOM 添加额外节点可以采用语法糖<></>来替代 Fragment&#xff0c;但在需要添加 key 的场景下不能使用此短语 import React, { PureComponent, Fragment } from &q…

Echarts 实现温度计

先上图 <div id="mainOne" style="width: 230px;height:130px;"></div> var dom1 = document.getElementById(mainOne) 核心代码 setTemperature(){var dom1 = document.getElementById(mainOne)var dom2 = document.getElementById(mainTw…

正则表达式与文本处理器

文本处理器三剑客&#xff1a;grep&#xff08;查找&#xff09; sed awk 正则表达式&#xff1a;由一类特殊字符以及文本字符所编写的一种模式&#xff0c;处理文本当中的内容 其中的一些字符不表示字符的字面含义&#xff0c;这些字符表示控制或者通配的功能 通配符&…

在分区工具上,格式化分区和删除分区. 两者有什么不一样吗?

1.格式化分区&#xff1a;就是重建文件系统&#xff0c;等于把目标分区的数据全部清掉。 删除分区&#xff1a;你删除后可以再重新分区&#xff0c;可以分区多个分区&#xff0c;前提是“删除分区”的大小足够大。分了区&#xff0c;还必须格式化&#xff0c;才能用。 只有分了…

掌握无人机遥感数据预处理的全链条理论与实践流程、典型农林植被性状的估算理论与实践方法、利用MATLAB进行编程实践(脚本与GUI开发)以及期刊论文插图制作等

目录 专题一 认识主被动无人机遥感数据 专题二 预处理无人机遥感数据 专题三 定量估算农林植被关键性状 专题四 期刊论文插图精细制作与Appdesigner应用开发 近地面无人机植被定量遥感与生理参数反演 更多推荐 遥感技术作为一种空间大数据手段&#xff0c;能够从多时、多…

LayUi之手风琴的趣味案例

&#x1f973;&#x1f973;Welcome Huihuis Code World ! !&#x1f973;&#x1f973; 接下来看看由辉辉所写的关于LayUi的相关操作吧 目录 &#x1f973;&#x1f973;Welcome Huihuis Code World ! !&#x1f973;&#x1f973; 一.手风琴是什么 二.手风琴在什么时候使用…

性能测试之性能问题分析

开始性能测试前需要了解的内容&#xff1a; 1、项目具体需求。 2、指标&#xff1a;响应时间在多少以内&#xff0c;并发数多少&#xff0c;tps多少&#xff0c;总tps多少&#xff0c;稳定性交易总量多少&#xff0c;事务成功率&#xff0c;交易波动范围&#xff0c;稳定运行时…

【iOS】—— 面向对象,Runtime,ARC等问题总结

对于暑假学习大多数是对之前学习的一个复习&#xff0c;在这里只做对之前学习欠缺知识的补充以及这些知识点涉及的一些问题&#xff0c;从问题入手学习。 文章目录 面向对象1.一个NSObject对象占多少内存&#xff1f;2.对象的isa指针指向哪里&#xff1f;3.OC的类信息存放在哪…

诚迈科技子公司智达诚远精耕智能驾驶,为商用落地注入创新力量

近期&#xff0c;工业和信息化部副部长辛国斌在新闻发布会上表示&#xff0c;将启动智能网联汽车准入和上路通行试点&#xff0c;组织开展城市级“车路云一体化”示范应用&#xff0c;将支持L3级及更高级别的自动驾驶功能商业化应用。根据工信部最新消息&#xff0c;《智能网联…

实际上手体验maven面对冲突Jar包的加载规则 | 京东云技术团队

一、问题背景 相信大家在日常的开发过程中都遇到过Jar包冲突的问题&#xff0c;emm&#xff0c;在最近处理业务需求时我也遇到了不同版本jar包冲突导致项目加载出错的问题。主要是一个完整的项目会不可避免的使用第三方的Jar包来实现功能开发&#xff0c;各种第三方包之间可能…

Python 3 拷贝、浅拷贝、直接引用

诸神缄默不语-个人CSDN博文目录 复杂的以后再补。 总的来说&#xff0c;像常数、字符串这种比较简单的变量无所谓&#xff0c;但是对于一些复杂对象&#xff08;比如list等&#xff09;&#xff0c;如果直接使ba&#xff0c;相当于直接把a的路径给了b&#xff0c;b这个对象的…

day35-Postman/ajax

0目录 1.postman 2.ajax 1.Postman 1.1 定义&#xff1a;postman用于测试http协议接口&#xff0c;无论是开发还是测试人员 1.2 Servlet中的doGet&#xff08;&#xff09;/doPost…