设计模式——迭代器设计模式(行为型)

news2025/7/23 15:45:57

摘要

本文详细介绍了迭代器设计模式,这是一种行为型设计模式,用于顺序访问集合对象中的元素,同时隐藏集合的内部结构。文章首先定义了迭代器设计模式并阐述了其核心角色,包括迭代器接口、具体迭代器、容器接口和具体容器。接着,文章通过 Java 标准库中的 Iterator 接口为例,展示了迭代器设计模式的结构和实现方式。此外,文章还探讨了迭代器设计模式的适用场景,包括适合和不适合使用该模式的情况,并通过金融风控的实战示例,展示了如何将迭代器设计模式与其他设计模式(如责任链模式、策略模式等)结合使用。最后,文章总结了迭代器设计模式与其他设计模式的组合使用方式。

1. 迭代器设计模式定义

迭代器设计模式(Iterator Pattern)是一种行为型设计模式,用于顺序访问一个集合对象中的元素,而又不暴露该对象的内部表示结构

1.1. 🔹 核心角色:

角色

说明

Iterator(迭代器接口)

定义访问和遍历元素的接口,如 hasNext()next()

ConcreteIterator(具体迭代器)

实现 Iterator接口,维护当前遍历位置。

Aggregate(容器接口)

定义创建迭代器对象的方法。

ConcreteAggregate(具体容器)

实现 Aggregate接口,返回该容器的迭代器。

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. 迭代器设计模式结构

  1. 迭代器 (Iterator) 接口声明了遍历集合所需的操作: 获取下一个元素、 获取当前位置和重新开始迭代等。
  2. 具体迭代器 (Concrete Iterators) 实现遍历集合的一种特定算法。 迭代器对象必须跟踪自身遍历的进度。 这使得多个迭代器可以相互独立地遍历同一集合。
  3. 集合 (Collection) 接口声明一个或多个方法来获取与集合兼容的迭代器。 请注意, 返回方法的类型必须被声明为迭代器接口, 因此具体集合可以返回各种不同种类的迭代器。
  4. 具体集合 (Concrete Collections) 会在客户端请求迭代器时返回一个特定的具体迭代器类实体。 你可能会琢磨, 剩下的集合代码在什么地方呢? 不用担心, 它也会在同一个类中。 只是这些细节对于实际模式来说并不重要, 所以我们将其省略了而已。
  5. 客户端 (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();
    }

    @Override
    public 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;
    }

    @Override
    public boolean hasNext() {
        return currentIndex < aggregate.size();
    }

    @Override
    public 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. ✅ 迭代器示例总结

组件

作用

Iterator 接口

提供统一遍历接口

ConcreteIterator

维护当前索引、实现遍历逻辑

Aggregate接口

提供创建迭代器方法

ConcreteAggregate

存储数据集合,并生成迭代器

4. 迭代器设计模式适合场景

迭代器设计模式的核心目的是提供统一的遍历接口,屏蔽容器内部的数据结构差异。下面是它适合与不适合的场景分析:

4.1. ✅ 适合使用迭代器设计模式的场景

场景

说明

容器类集合遍历

当你希望对集合(数组、列表、树、图等)进行遍历,不暴露其内部结构。

多种容器结构共用遍历方式

例如支持 ListSetMap、自定义集合类都实现一个标准的迭代器接口,便于切换。

需要多种遍历方式

如顺序、逆序、跳跃等不同的遍历策略,可以封装成不同的迭代器类。

自定义复杂聚合对象遍历

比如订单->商品->商品属性 这种层级结构,可以通过迭代器隐藏细节,统一接口。

希望解耦容器与遍历逻辑

把“遍历逻辑”从容器中抽离出来,符合单一职责、开闭原则。

支持多并发遍历操作

每个迭代器对象互不干扰,可以实现并发读操作。

4.2. ❌ 不适合使用迭代器设计模式的场景

场景

原因

集合结构非常简单,且不会改变

比如只有 1~2 个元素,直接使用 for-each 更高效,没必要引入额外迭代器类。

对遍历性能要求极高的系统(高频大数据处理)

自定义迭代器层级增加方法调用,可能影响性能,如在实时交易撮合、低延迟系统中。

对象间耦合必须最小,不能增加接口依赖

引入 Iterator接口会额外增加模块之间依赖,不符合某些架构设计原则。

需要对遍历过程进行复杂控制(如跳转、回溯)

此时可能更适合状态机模式或访问者模式,对每一步状态进行更复杂管理。

遍历逻辑需要携带大量上下文或中间状态

简单的迭代器不适合包含太多状态持久性,需要扩展为上下文感知处理器模式。

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 {
    
    @Override
    public 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 {
    @Override
    public String getName() {
        return "黑名单规则";
    }

    @Override
    protected boolean doEvaluate(RiskRequest request) {
        return !request.isInBlackList();
    }
}

@Component
public class AgeLimitRule extends AbstractRiskRule {
    @Override
    public String getName() {
        return "年龄限制规则";
    }

    @Override
    protected boolean doEvaluate(RiskRequest request) {
        return request.getAge() >= 18;
    }
}

@Component
public class CreditScoreRule extends AbstractRiskRule {
    @Override
    public String getName() {
        return "信用分规则";
    }

    @Override
    protected boolean doEvaluate(RiskRequest request) {
        return request.getCreditScore() >= 600;
    }
}

5.6. RuleChainContext(责任链 + 迭代器)

@Component
public class RuleChainContext {

    private final List<RiskRule> ruleList;

    @Autowired
    public 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 {
    
    @Autowired
    private RuleChainContext ruleChainContext;

    public RiskResponse evaluate(RiskRequest request) {
        return ruleChainContext.process(request);
    }
}

5.8. ✅ 使用方式示例

@RestController
@RequestMapping("/risk")
public class RiskController {

    @Autowired
    private RiskService riskService;

    @PostMapping("/check")
    public RiskResponse check(@RequestBody RiskRequest request) {
        return riskService.evaluate(request);
    }
}

5.9. 🧠 总结:设计模式用法回顾

模式

用法说明

策略模式

每一个规则都是一个策略,实现 RiskRule接口

责任链模式

所有规则顺序执行,遇到失败立即终止

迭代器模式

通过 Iterator<RiskRule>遍历所有策略规则

模板方法模式

抽象类定义执行流程,子类重写核心判断逻辑

注解注入

使用 @Component+ @Autowired实现 Spring 自动装配

如需添加动态配置规则链顺序、启用规则开关、分组规则集等功能,可以进一步引入配置中心或数据库控制,支持高扩展。

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

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

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

相关文章

android-studio-2024.3.2.14如何用WIFI连接到手机(给数据线说 拜拜!)

原文&#xff1a;Android不用数据线就能调试真机的方法—给数据线说 拜拜&#xff01;&#xff08;adb远程调试&#xff09; android-studio-2024.3.2.14是最新的版本&#xff0c;如何连接到手机&#xff0c;可用WIFI&#xff0c;可不用数据线&#xff0c;拜拜 第一步&#xf…

js 动画库、2048核心逻辑、面试题add[1][2][3]+4

1、js 动画库 web animation api &#xff08;1&#xff09;初始化代码 hmtl、css 部分 初始化全局背景黑色初始化黄色小球 js 部分 监听全局点击事件创建并添加元素 class"pointer" 的 div 标签 设置 left、top 位置监听动画结束事件&#xff0c;移除该元素 定位小…

华为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 归一化的图片 两个长度为三的数组&#xff0c;分别表示三个通道的平均值和标准差 Resize&#xff08;&#xff09; Compose&#xff08;&#xff09; 合并执行功能&#xff0c;输入进去一个列表&a…

Pytorch知识点2

Pytorch知识点 1、官方教程2、张量&#x1f9f1; 0、数组概念&#x1f9f1; 1. 创建张量&#x1f4d0; 2. 张量形状与维度&#x1f522; 3. 张量数据类型➗ 4. 张量的数学与逻辑操作&#x1f504; 5. 张量的就地操作&#x1f4e6; 6. 复制张量&#x1f680; 7. 将张量移动到加速…

AWS API Gateway 配置WAF(中国区)

问题 需要给AWS API Gateway配置WAF。 AWS WAF设置 打开AWS WAF首页&#xff0c;开始创建和配置WAF&#xff0c;如下图&#xff1a; 设置web acl名称&#xff0c;然后开始添加aws相关资源&#xff0c;如下图&#xff1a; 选择资源类型&#xff0c;但是&#xff0c;我这里出…

【前端面经】百度一面

写在前面&#xff1a;面经只是记录博主遇到的题目。每题的答案在编写文档的时候已经有问过deepseek&#xff0c;它只是一种比较普世的答案&#xff0c;要学得深入还是靠自己 Q&#xff1a; <html><style>.a {background-color: red;width: 200px;height: 100px;}…

[免费]微信小程序网上花店系统(SpringBoot后端+Vue管理端)【论文+源码+SQL脚本】

大家好&#xff0c;我是java1234_小锋老师&#xff0c;看到一个不错的微信小程序网上花店系统(SpringBoot后端Vue管理端)【论文源码SQL脚本】&#xff0c;分享下哈。 项目视频演示 【免费】微信小程序网上花店系统(SpringBoot后端Vue管理端) Java毕业设计_哔哩哔哩_bilibili 项…

css使用scoped之后样式失效问题

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

【NLP】将 LangChain 与模型上下文协议 (MCP) 结合使用

&#x1f50e;大家好&#xff0c;我是Sonhhxg_柒&#xff0c;希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流&#x1f50e; &#x1f4dd;个人主页&#xff0d;Sonhhxg_柒的博客_CSDN博客 &#x1f4c3; &#x1f381;欢迎各位→点赞…

使用NMEA Tools生成GPS轨迹图

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

1. pytorch手写数字预测

1. pytorch手写数字预测 1.背景2.准备数据集2.定义模型3.dataloader和训练4.训练模型5.测试模型6.保存模型 1.背景 因为自身的研究方向是多模态目标跟踪&#xff0c;突然对其他的视觉方向产生了兴趣&#xff0c;所以心血来潮的回到最经典的视觉任务手写数字预测上来&#xff0…

AXI 协议补充(二)

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

Linux 基础指令入门指南:解锁命令行的实用密码

文章目录 引言&#xff1a;Linux 下基本指令常用选项ls 指令pwd 命令cd 指令touch 指令mkdir 指令rmdir 指令 && rm 指令man 指令cp 指令mv 指令cat 指令more 指令less 指令head 指令tail 指令date 指令cal 指令find 指令按文件名搜索按文件大小搜索按修改时间搜索按文…

标准精读:2025 《可信数据空间 技术架构》【附全文阅读】

《可信数据空间 技术架构》规范了可信数据空间的技术架构,明确其作为国家数据基础设施的定位,以数字合约和使用控制技术为核心,涵盖功能架构(含服务平台与接入连接器的身份管理、目录管理、数字合约管理等功能)、业务流程(登记、发现、创建空间及数据流通利用)及安全要求…

山东大学软件学院项目实训-基于大模型的模拟面试系统-面试官和面试记录的分享功能(2)

本文记录在发布文章时&#xff0c;可以添加自己创建的面试官和面试记录到文章中这一功能的实现。 前端 首先是在原本的界面的底部添加了两个多选框&#xff08;后期需要美化调整&#xff09; 实现的代码&#xff1a; <el-col style"margin-top: 1rem;"><e…

Webug4.0靶场通关笔记05- 第5关SQL注入之过滤关键字

目录 一、代码审计 1、源码分析 2、SQL注入分析 &#xff08;1&#xff09;大小写绕过 &#xff08;2&#xff09;双写绕过 二、第05关 过滤型注入 1、进入靶场 2、sqlmap渗透 &#xff08;1&#xff09;bp抓包保存报文 &#xff08;2&#xff09;sqlmap渗透 &…

ONLYOFFICE文档API:更强的安全功能

在数字化办公时代&#xff0c;文档的安全性与隐私保护已成为企业和个人用户的核心关切。如何确保信息在存储、传输及协作过程中的安全&#xff0c;是开发者与IT管理者亟需解决的问题。ONLYOFFICE作为一款功能强大的开源办公套件&#xff0c;不仅提供了高效的文档编辑与协作体验…

解析楼宇自控系统:分布式结构的核心特点与优势展现

在建筑智能化发展的进程中&#xff0c;楼宇自控系统作为实现建筑高效运行与管理的关键&#xff0c;其系统结构的选择至关重要。传统的集中式楼宇自控系统在面对日益复杂的建筑环境和多样化的管理需求时&#xff0c;逐渐暴露出诸多弊端&#xff0c;如可靠性低、扩展性差、响应速…

C#数字图像处理(三)

文章目录 前言1.图像平移1.1 图像平移定义1.2 图像平移编程实例 2.图像镜像2.1 图像镜像定义2.2 图像镜像编程实例 3.图像缩放3.1 图像缩放定义3.2 灰度插值法3.3 图像缩放编程实例 4.图像旋转4.1 图像旋转定义4.2 图像旋转编程实例 前言 在某种意义上来说&#xff0c;图像的几…