设计模式——迭代器设计模式(行为型)
摘要
本文详细介绍了迭代器设计模式,这是一种行为型设计模式,用于顺序访问集合对象中的元素,同时隐藏集合的内部结构。文章首先定义了迭代器设计模式并阐述了其核心角色,包括迭代器接口、具体迭代器、容器接口和具体容器。接着,文章通过 Java 标准库中的 Iterator 接口为例,展示了迭代器设计模式的结构和实现方式。此外,文章还探讨了迭代器设计模式的适用场景,包括适合和不适合使用该模式的情况,并通过金融风控的实战示例,展示了如何将迭代器设计模式与其他设计模式(如责任链模式、策略模式等)结合使用。最后,文章总结了迭代器设计模式与其他设计模式的组合使用方式。
1. 迭代器设计模式定义
迭代器设计模式(Iterator Pattern)是一种行为型设计模式,用于顺序访问一个集合对象中的元素,而又不暴露该对象的内部表示结构。
1.1. 🔹 核心角色:
角色 | 说明 |
Iterator(迭代器接口) | 定义访问和遍历元素的接口,如 |
ConcreteIterator(具体迭代器) | 实现 |
Aggregate(容器接口) | 定义创建迭代器对象的方法。 |
ConcreteAggregate(具体容器) | 实现 |
Java 标准库中广泛使用了该模式,例如 java.util.Iterator
接口就是该模式的典型实现。
List<String> list = new ArrayList<>();
list.add("A");
list.add("B");
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {System.out.println(iterator.next());
}
2. 迭代器设计模式结构
- 迭代器 (Iterator) 接口声明了遍历集合所需的操作: 获取下一个元素、 获取当前位置和重新开始迭代等。
- 具体迭代器 (Concrete Iterators) 实现遍历集合的一种特定算法。 迭代器对象必须跟踪自身遍历的进度。 这使得多个迭代器可以相互独立地遍历同一集合。
- 集合 (Collection) 接口声明一个或多个方法来获取与集合兼容的迭代器。 请注意, 返回方法的类型必须被声明为迭代器接口, 因此具体集合可以返回各种不同种类的迭代器。
- 具体集合 (Concrete Collections) 会在客户端请求迭代器时返回一个特定的具体迭代器类实体。 你可能会琢磨, 剩下的集合代码在什么地方呢? 不用担心, 它也会在同一个类中。 只是这些细节对于实际模式来说并不重要, 所以我们将其省略了而已。
- 客户端 (Client) 通过集合和迭代器的接口与两者进行交互。 这样一来客户端无需与具体类进行耦合, 允许同一客户端代码使用各种不同的集合和迭代器。客户端通常不会自行创建迭代器, 而是会从集合中获取。 但在特定情况下, 客户端可以直接创建一个迭代器 (例如当客户端需要自定义特殊迭代器时)。
2.1. 迭代器类图
2.2. 迭代器时序图
3. 迭代器设计模式实现方式
迭代器设计模式的实现方式主要包括自定义以下四个关键角色:容器接口、具体容器、迭代器接口、具体迭代器。下面是标准的实现步骤(以 Java 为例)。
3.1. 🔹 定义迭代器接口 Iterator
public interface Iterator<T> {boolean hasNext();T next();
}
3.2. 🔹 定义聚合容器接口 Aggregate
public interface Aggregate<T> {Iterator<T> createIterator();
}
3.3. 🔹 实现具体容器 ConcreteAggregate
public class ConcreteAggregate<T> implements Aggregate<T> {private List<T> items = new ArrayList<>();public void add(T item) {items.add(item);}public T get(int index) {return items.get(index);}public int size() {return items.size();}@Overridepublic Iterator<T> createIterator() {return new ConcreteIterator<>(this);}
}
3.4. 🔹 实现具体迭代器 ConcreteIterator
public class ConcreteIterator<T> implements Iterator<T> {private ConcreteAggregate<T> aggregate;private int currentIndex = 0;public ConcreteIterator(ConcreteAggregate<T> aggregate) {this.aggregate = aggregate;}@Overridepublic boolean hasNext() {return currentIndex < aggregate.size();}@Overridepublic T next() {return aggregate.get(currentIndex++);}
}
3.5. 🔹 使用示例
public class Main {public static void main(String[] args) {ConcreteAggregate<String> container = new ConcreteAggregate<>();container.add("A");container.add("B");container.add("C");Iterator<String> iterator = container.createIterator();while (iterator.hasNext()) {System.out.println(iterator.next());}}
}
3.6. ✅ 迭代器示例总结
组件 | 作用 |
| 提供统一遍历接口 |
| 维护当前索引、实现遍历逻辑 |
| 提供创建迭代器方法 |
| 存储数据集合,并生成迭代器 |
4. 迭代器设计模式适合场景
迭代器设计模式的核心目的是提供统一的遍历接口,屏蔽容器内部的数据结构差异。下面是它适合与不适合的场景分析:
4.1. ✅ 适合使用迭代器设计模式的场景
场景 | 说明 |
✅ 容器类集合遍历 | 当你希望对集合(数组、列表、树、图等)进行遍历,不暴露其内部结构。 |
✅ 多种容器结构共用遍历方式 | 例如支持 |
✅ 需要多种遍历方式 | 如顺序、逆序、跳跃等不同的遍历策略,可以封装成不同的迭代器类。 |
✅ 自定义复杂聚合对象遍历 | 比如订单->商品->商品属性 这种层级结构,可以通过迭代器隐藏细节,统一接口。 |
✅ 希望解耦容器与遍历逻辑 | 把“遍历逻辑”从容器中抽离出来,符合单一职责、开闭原则。 |
✅ 支持多并发遍历操作 | 每个迭代器对象互不干扰,可以实现并发读操作。 |
4.2. ❌ 不适合使用迭代器设计模式的场景
场景 | 原因 |
❌ 集合结构非常简单,且不会改变 | 比如只有 1~2 个元素,直接使用 for-each 更高效,没必要引入额外迭代器类。 |
❌ 对遍历性能要求极高的系统(高频大数据处理) | 自定义迭代器层级增加方法调用,可能影响性能,如在实时交易撮合、低延迟系统中。 |
❌ 对象间耦合必须最小,不能增加接口依赖 | 引入 |
❌ 需要对遍历过程进行复杂控制(如跳转、回溯) | 此时可能更适合状态机模式或访问者模式,对每一步状态进行更复杂管理。 |
❌ 遍历逻辑需要携带大量上下文或中间状态 | 简单的迭代器不适合包含太多状态持久性,需要扩展为上下文感知处理器模式。 |
4.3. ✅ 举个金融风控例子
适合:遍历用户的多个信用卡账户,统一处理风控评分。
for (Account account : userAccountIterator) {scoreService.evaluate(account);
}
不适合:实时交易撮合引擎中,大量订单队列需要毫秒级处理,使用数组/队列遍历更高效,不宜引入自定义迭代器。
5. 迭代器设计模式实战示例
下面是一个在风控场景下,使用迭代器设计模式 + Spring 注解注入方式 实现的示例,适合处理多个风控规则依次执行的业务逻辑。
5.1. 🎯 场景描述
对信贷申请进行风控判断。每个申请会通过一系列规则(如年龄检查、信用分检查),每条规则是一个策略,同时这些策略按顺序组成一个责任链。为了支持动态控制规则顺序,还使用迭代器遍历规则链。
5.2. ☕️ 项目结构
com.example.risk
├── RiskRule.java # 策略接口
├── AbstractRiskRule.java # 模板实现
├── BlackListRule.java # 名单规则
├── AgeLimitRule.java # 年龄限制规则
├── CreditScoreRule.java # 信用分规则
├── RuleChainContext.java # 责任链 + 迭代器控制
├── RiskRequest.java # 入参
├── RiskResponse.java # 出参
├── RuleConfig.java # 自动注入规则列表
└── RiskService.java # 风控服务入口
5.3. 风控请求/响应对象
@Data
public class RiskRequest {private String userId;private int age;private int creditScore;private boolean inBlackList;
}@Data
public class RiskResponse {private boolean passed = true;private String failedReason;
}
5.4. 策略接口和抽象类(策略 + 模板)
public interface RiskRule {boolean evaluate(RiskRequest request, RiskResponse response);String getName();
}public abstract class AbstractRiskRule implements RiskRule {@Overridepublic boolean evaluate(RiskRequest request, RiskResponse response) {if (!doEvaluate(request)) {response.setPassed(false);response.setFailedReason(getName());return false;}return true;}protected abstract boolean doEvaluate(RiskRequest request);
}
5.5. 各种规则实现(策略 + 责任链)
@Component
public class BlackListRule extends AbstractRiskRule {@Overridepublic String getName() {return "黑名单规则";}@Overrideprotected boolean doEvaluate(RiskRequest request) {return !request.isInBlackList();}
}@Component
public class AgeLimitRule extends AbstractRiskRule {@Overridepublic String getName() {return "年龄限制规则";}@Overrideprotected boolean doEvaluate(RiskRequest request) {return request.getAge() >= 18;}
}@Component
public class CreditScoreRule extends AbstractRiskRule {@Overridepublic String getName() {return "信用分规则";}@Overrideprotected boolean doEvaluate(RiskRequest request) {return request.getCreditScore() >= 600;}
}
5.6. RuleChainContext(责任链 + 迭代器)
@Component
public class RuleChainContext {private final List<RiskRule> ruleList;@Autowiredpublic RuleChainContext(List<RiskRule> ruleList) {// 可排序或通过配置动态控制顺序this.ruleList = ruleList;}public RiskResponse process(RiskRequest request) {RiskResponse response = new RiskResponse();Iterator<RiskRule> iterator = ruleList.iterator();while (iterator.hasNext()) {// 迭代器进行遍历RiskRule rule = iterator.next();if (!rule.evaluate(request, response)) {break; // 短路失败}}return response;}
}
5.7. Service调用入口
@Service
public class RiskService {@Autowiredprivate RuleChainContext ruleChainContext;public RiskResponse evaluate(RiskRequest request) {return ruleChainContext.process(request);}
}
5.8. ✅ 使用方式示例
@RestController
@RequestMapping("/risk")
public class RiskController {@Autowiredprivate RiskService riskService;@PostMapping("/check")public RiskResponse check(@RequestBody RiskRequest request) {return riskService.evaluate(request);}
}
5.9. 🧠 总结:设计模式用法回顾
模式 | 用法说明 |
策略模式 | 每一个规则都是一个策略,实现 |
责任链模式 | 所有规则顺序执行,遇到失败立即终止 |
迭代器模式 | 通过 |
模板方法模式 | 抽象类定义执行流程,子类重写核心判断逻辑 |
注解注入 | 使用 |
如需添加动态配置规则链顺序、启用规则开关、分组规则集等功能,可以进一步引入配置中心或数据库控制,支持高扩展。
6. 迭代器设计模式思考
6.1. 🔁 常与迭代器组合使用的设计模式
在实战开发中,迭代器设计模式(Iterator Pattern)通常与以下几种设计模式组合使用,以增强集合结构的灵活性、扩展性、解耦性,尤其在领域模型、规则处理、任务调度等系统中非常常见:
组合模式 | 搭配原因/典型场景 |
责任链模式 | 顺序执行规则或任务链,迭代器负责链路遍历 |
策略模式 | 每个元素是一个策略(如规则或算法),通过迭代器遍历并执行 |
组合模式 | 组合结构的子元素通过迭代器统一遍历(如树状结构遍历) |
模板方法模式 | 元素结构统一,遍历时调用公共模板方法,保留定制扩展点 |
观察者模式 | 遍历一组观察者并触发通知 |
命令模式 | 遍历一组命令并逐一执行(或回滚) |
装饰器模式 | 每一层装饰器通过迭代器包装组合 |
工厂方法模式 | 工厂批量创建可遍历的对象集合 |
6.1.1. 与责任链模式
场景:规则引擎、风控审核、流程编排
- 每个 handler/规则实现
RuleHandler
接口 - 用
List<RuleHandler>
通过迭代器逐个执行,遇失败中断
for (RuleHandler handler : handlers) {if (!handler.handle(context)) {break;}
}
6.1.2. 与策略模式
场景:算法选择、数据转换器、规则过滤器
- 每个元素是一个策略类(如计算利息、折扣策略)
- 迭代器控制策略的执行顺序,支持动态扩展
6.1.3. 与组合模式
场景:菜单树、组织结构、数据表头嵌套结构
- 组合结构的节点可以通过迭代器实现统一的遍历
6.1.4. 与模板方法模式
场景:日志采集、批量数据导出、统一操作步骤
- 各子类复用固定遍历结构,通过
doXXX()
定制操作逻辑
6.1.5. 与命令模式
场景:批量命令处理、回滚事务、脚本执行
- 一组命令对象放入集合,通过迭代器逐个执行或撤销
模式组合 | 是否常见 | 典型用途 |
迭代器 + 责任链 | ✅ | 流程控制、规则判断 |
迭代器 + 策略 | ✅ | 动态决策执行、多策略适配 |
迭代器 + 组合 | ✅ | 树形结构统一遍历 |
迭代器 + 模板方法 | ✅ | 标准流程 + 扩展处理 |
迭代器 + 命令 | ✅ | 操作回放、事务控制 |
迭代器 + 观察者 | 🟡 | 通知一组监听者 |
迭代器 + 单例等 | ❌ | 不适合,与集合行为无关 |
博文参考
- 迭代器设计模式
- 设计模式之迭代器模式 | DESIGN
相关文章:

设计模式——迭代器设计模式(行为型)
摘要 本文详细介绍了迭代器设计模式,这是一种行为型设计模式,用于顺序访问集合对象中的元素,同时隐藏集合的内部结构。文章首先定义了迭代器设计模式并阐述了其核心角色,包括迭代器接口、具体迭代器、容器接口和具体容器。接着&a…...

android-studio-2024.3.2.14如何用WIFI连接到手机(给数据线说 拜拜!)
原文:Android不用数据线就能调试真机的方法—给数据线说 拜拜!(adb远程调试) android-studio-2024.3.2.14是最新的版本,如何连接到手机,可用WIFI,可不用数据线,拜拜 第一步…...
[特殊字符] xbatis 一款好用 ORM 框架 1.8.8-M2 发布,节省 1/3 代码和时间的框架!!!
1.8.8-M2 更新内容: 1:优化默认值,对同一类减少重复调用2:优化分页,支持 limit (-1) 进行忽略分页3:优化 UpdateChain.set;支持.set (SysUser::getVersion, c -> c.plus (1))4:优化 @Fetch, 已增强,无法配置 groupby、forceUseIn(已去除)5:增强 @Fetch,支持中间…...

js 动画库、2048核心逻辑、面试题add[1][2][3]+4
1、js 动画库 web animation api (1)初始化代码 hmtl、css 部分 初始化全局背景黑色初始化黄色小球 js 部分 监听全局点击事件创建并添加元素 class"pointer" 的 div 标签 设置 left、top 位置监听动画结束事件,移除该元素 定位小…...

华为OD机试真题——书籍叠放(2025B卷:200分)Java/python/JavaScript/C/C++/GO最佳实现
2025 B卷 200分 题型 本专栏内全部题目均提供Java、python、JavaScript、C、C++、GO六种语言的最佳实现方式; 并且每种语言均涵盖详细的问题分析、解题思路、代码实现、代码详解、3个测试用例以及综合分析; 本文收录于专栏:《2025华为OD真题目录+全流程解析+备考攻略+经验分…...

PyTorch-Transforms的使用(二)
对图像进行处理 安装open cv ctrlP 看用法 ToTensor的使用 常见的Transforms 归一化的图片 两个长度为三的数组,分别表示三个通道的平均值和标准差 Resize() Compose() 合并执行功能,输入进去一个列表&a…...

Pytorch知识点2
Pytorch知识点 1、官方教程2、张量🧱 0、数组概念🧱 1. 创建张量📐 2. 张量形状与维度🔢 3. 张量数据类型➗ 4. 张量的数学与逻辑操作🔄 5. 张量的就地操作📦 6. 复制张量🚀 7. 将张量移动到加速…...
Java详解LeetCode 热题 100(23):LeetCode 206. 反转链表(Reverse Linked List)详解
文章目录 1. 题目描述1.1 链表节点定义 2. 理解题目2.1 反转前后对比2.2 核心思路 3. 解法一:迭代法(三指针法)3.1 算法思路3.2 详细图解3.3 Java代码实现3.4 代码执行过程演示3.5 执行结果示例3.6 优化版本(简化代码)…...
StarRocks部署方案详解:从单机到分布式集群
#### 一、引言 StarRocks(原名DorisDB)是一款高性能的MPP(大规模并行处理)分析型数据库,支持实时查询、高并发和复杂分析场景。其基于列式存储和向量化执行引擎的设计,使其在大数据OLAP领域表现优异。本文…...

AWS API Gateway 配置WAF(中国区)
问题 需要给AWS API Gateway配置WAF。 AWS WAF设置 打开AWS WAF首页,开始创建和配置WAF,如下图: 设置web acl名称,然后开始添加aws相关资源,如下图: 选择资源类型,但是,我这里出…...

【前端面经】百度一面
写在前面:面经只是记录博主遇到的题目。每题的答案在编写文档的时候已经有问过deepseek,它只是一种比较普世的答案,要学得深入还是靠自己 Q: <html><style>.a {background-color: red;width: 200px;height: 100px;}…...
嵌入式学习笔记 - freeRTOS 动态创建任务跟静态创建任务的区别,以及内存回收问题
FreeRTOS动态创建任务和静态创建任务各有优缺点,选择哪种方式取决于具体的应用场景和需求。 一 动态创建任务 优点: 灵活性高:动态任务在运行时通过pvPortMalloc()动态分配内存,系统自动管理栈和任务控制块…...

[免费]微信小程序网上花店系统(SpringBoot后端+Vue管理端)【论文+源码+SQL脚本】
大家好,我是java1234_小锋老师,看到一个不错的微信小程序网上花店系统(SpringBoot后端Vue管理端)【论文源码SQL脚本】,分享下哈。 项目视频演示 【免费】微信小程序网上花店系统(SpringBoot后端Vue管理端) Java毕业设计_哔哩哔哩_bilibili 项…...
如何给老旧 iOS App 添加安全保护?用 Ipa Guard 对 IPA 文件混淆加固实录
在大多数安全讨论中,我们习惯关注新项目的安全性,从代码结构、API 设计、用户认证机制出发,构建完善的防护体系。但现实是,很多开发者都在维护一些年久失修的老项目——技术架构老旧、团队成员流失、源码混乱甚至缺失。 我最近接…...
C#语音录制:使用NAudio库实现语音录制功能详解
C#语音录制:使用NAudio库实现语音录制功能详解 在音频处理领域,C# 凭借其强大的生态系统和丰富的类库,为开发者提供了便捷的开发工具。NAudio 库就是其中一款用于音频处理的优秀开源库,它支持多种音频格式和音频设备操作。今天&a…...
[蓝桥杯]缩位求和
缩位求和 题目描述 在电子计算机普及以前,人们经常用一个粗略的方法来验算四则运算是否正确。 比如:248153720248153720 把乘数和被乘数分别逐位求和,如果是多位数再逐位求和,直到是 1 位数,得 24814>14524814…...
MySQ-8.42 MGR 组复制部署及详解
目录 1 MGR要求 2 操作系统信息和软件版本 3 集群架构图 4 MySQL MGR 主库部署步骤 1 MGR要求 InnoDB 存储引擎 表上必须存在主键或唯一非空索引 MGR可允许的最大节点9个 2 操作系统信息和软件版本 rootu24-mysql-mgr-42:~# cat /etc/issue Ubuntu 24.04.2 LTS \n \l mysql…...

css使用scoped之后样式失效问题
项目中的vue代码原本用的style标签来写css,现在想改成<style langscss scoped>,但是改完之后发现样式不对: 原来是: 将style改成scoped之后变成了:检查发现是之前定义的一些变量无法被识别,导致这些样…...

【NLP】将 LangChain 与模型上下文协议 (MCP) 结合使用
🔎大家好,我是Sonhhxg_柒,希望你看完之后,能对你有所帮助,不足请指正!共同学习交流🔎 📝个人主页-Sonhhxg_柒的博客_CSDN博客 📃 🎁欢迎各位→点赞…...

使用NMEA Tools生成GPS轨迹图
前言 在现代科技快速发展的时代,GPS定位技术已经广泛应用于各种领域,如导航、物流、运动追踪等。为了获取和分析GPS数据,我们常常需要使用一些专业的工具。本文将详细介绍如何使用一款名为“NMEA Tools”的APK应用,结合GPSVisual…...

1. pytorch手写数字预测
1. pytorch手写数字预测 1.背景2.准备数据集2.定义模型3.dataloader和训练4.训练模型5.测试模型6.保存模型 1.背景 因为自身的研究方向是多模态目标跟踪,突然对其他的视觉方向产生了兴趣,所以心血来潮的回到最经典的视觉任务手写数字预测上来࿰…...
vs中添加三方库的流程
在Visual Studio(VS)中添加第三方库(如OpenCV、PCL等)的流程可以分为以下几个步骤:安装库、配置项目、编写代码。以下是详细的步骤说明: 1. 安装第三方库 首先,需要下载并安装所需的第三方库。…...
JAVASE面相对象进阶之static
JavaSE 面向对象进阶之 static 一、static 的核心作用 static 是 Java 中用于修饰成员(属性/方法)的关键字,作用是让成员与类直接关联,而非依赖对象存在。 二、static 修饰属性(静态变量) 特点…...
深入解析 Redis Cluster 架构与实现(一)
#作者:stackofumbrella 文章目录 Redis Cluster特点Redis Cluster与其它集群模式的区别集群目标性能hash tagsMutli-key操作Cluster Bus安全写入(write safety)集群节点的属性集群拓扑节点间handshake重定向与reshardingMOVED重定向ASK重定向…...
(12)java+ selenium->元素定位大法之By_link_text
1.简介 本章节介绍元素定位中的link_text,顾名思义是通过链接定位的(官方说法:超链接文本定位)。什么是link_text呢,就是我们在任何一个网页上都可以看到有一个或者多个链接,上面有一个文字描述,点击这个文字,就可以跳转到其他页面。这个就是link_Text。 注意:link_t…...
数据库MySQL集群MGR
一、MGR原理 一、基本定义 MGR(MySQL Group Replication) 是 MySQL 官方推出的一种高可用、高可靠的数据库集群解决方案,基于分布式系统理论(如 Paxos 协议变种)实现,主要用于构建强一致性的主从复制集群…...
Ubuntu22.04 安装 ROS2 Humble
ROS2 Documentation: Humble Ubuntu 22.04 对应的 ROS 2 版本是 ROS 2 Humble Hawksbill (LTS)。 1.设置系统区域 确保区域设置支持UTF-8 sudo apt update && sudo apt install locales sudo locale-gen en_US en_US.UTF-8 sudo update-locale LC_ALLen_US.UTF-8 L…...
Spring Boot,注解,@RestController
RestController 是 Spring MVC 中用于创建 RESTful Web 服务的核心注解。 RestController 核心知识点 REST 作用: RestController 是一个方便的组合注解,它结合了 Controller 和 ResponseBody 两个注解。 Controller: 将类标记为一个控制器,使其能够处理…...
C++中新式类型转换static_cast、const_cast、dynamic_cast、reinterpret_cast
C中新式类型转换static_cast、const_cast、dynamic_cast、reinterpret_cast 在C中,新式类型转换(也称为强制类型转换)是C标准引入的一种更安全、更明确的类型转换方式,用以替代C语言风格的类型转换。C提供了四种新式类型转换操作…...

AXI 协议补充(二)
axi协议存在slave 和master 之间的数据交互,在ahb ,axi-stream 高速接口 ,叠加大位宽代码逻辑中,往往有时序问题,valid 和ready 的组合电路中的问题引发的时序问题较多。 本文根据axi 协议和现有解决反压造成的时序问题的方法做一个详细的科普。 1. 解决时序问题的方法:…...