Go语言设计模式之迭代器模式Iterator

news/2025/2/25 5:24:10

迭代器模式 Iterator

提供了一种方法顺序访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部表示。迭代器模式的核心思想是将遍历逻辑从聚合对象中分离出来,使得聚合对象和遍历逻辑可以独立变化。

实际应用场景

  1. 集合类库:
    如 Go 的 slice、map 等集合类型,可以通过迭代器模式提供统一的遍历接口。
  2. 数据库查询结果:
    数据库查询结果可以封装为一个聚合对象,并提供迭代器遍历查询结果。
  3. 文件系统遍历:
    文件系统中的目录和文件可以封装为一个聚合对象,并提供迭代器遍历文件系统。
  4. 树形结构遍历:
    树形结构(如二叉树、多叉树)可以提供多种遍历方式(如深度优先、广度优先)。

假设我们有一个集合类 BookCollection,它包含多本书。我们需要实现一个迭代器,用于遍历这个集合

package main

import "fmt"

// Book 定义书籍结构体
type Book struct {
  Title  string
  Author string
}

// Iterator 定义迭代器接口
type Iterator interface {
  HasNext() bool
  Next() *Book
}

// BookIterator 是具体迭代器
type BookIterator struct {
  books    []*Book
  position int
}

func (b *BookIterator) HasNext() bool {
  return b.position < len(b.books)
}

func (b *BookIterator) Next() *Book {
  if b.HasNext() {
    book := b.books[b.position]
    b.position++
    return book
  }
  return nil
}

// Aggregate 定义聚合接口
type Aggregate interface {
  CreateIterator() Iterator
}

// BookCollection 是具体聚合
type BookCollection struct {
  books []*Book
}

func (b *BookCollection) CreateIterator() Iterator {
  return &BookIterator{books: b.books}
}

func main() {
  // 创建书籍集合
  collection := &BookCollection{
    books: []*Book{
      {Title: "The Go Programming Language", Author: "Alan A. A. Donovan"},
      {Title: "Design Patterns", Author: "Erich Gamma"},
      {Title: "Clean Code", Author: "Robert C. Martin"},
    },
  }

  // 创建迭代器
  iterator := collection.CreateIterator()

  // 遍历集合
  for iterator.HasNext() {
    book := iterator.Next()
    fmt.Printf("Title: %s, Author: %s\n", book.Title, book.Author)
  }
}

代码结构分析:

Book结构体:

  • 存储书籍信息,包含Title(书名)和Author(作者)两个字段。

Iterator接口:

  • 定义迭代器的基本方法:HasNext()(检查是否有下一个元素)和Next()(获取下一个元素)。

BookIterator结构体:

  • 实现Iterator接口,包含书籍集合和当前位置索

引。

  • HasNext()检查索引是否越界。
  • Next()返回当前书籍并移动索引,若无元素则返回nil。

Aggregate接口:

  • 定义创建迭代器的方法CreateIterator()。

BookCollection结构体:

  • 存储书籍集合,并实现Aggregate接口来返回关联的迭代器。

模式扩展

扩展场景 1:树形结构的遍历
需求:遍历二叉树的不同顺序(前序、中序、后序)

// 树节点结构
type TreeNode struct {
    Value int
    Left  *TreeNode
    Right *TreeNode
}

// 前序迭代器
type PreOrderIterator struct {
    stack []*TreeNode
}

func NewPreOrderIterator(root *TreeNode) *PreOrderIterator {
    if root == nil {
        return &PreOrderIterator{stack: []*TreeNode{}}
    }
    return &PreOrderIterator{stack: []*TreeNode{root}}
}

func (it *PreOrderIterator) HasNext() bool {
    return len(it.stack) > 0
}

func (it *PreOrderIterator) Next() *TreeNode {
    node := it.stack[len(it.stack)-1]
    it.stack = it.stack[:len(it.stack)-1]
    
    if node.Right != nil {
        it.stack = append(it.stack, node.Right)
    }
    if node.Left != nil {
        it.stack = append(it.stack, node.Left)
    }
    return node
}

// 使用示例
func main() {
    root := &TreeNode{Value: 1,
        Left:  &TreeNode{Value: 2},
        Right: &TreeNode{Value: 3},
    }
    
    it := NewPreOrderIterator(root)
    for it.HasNext() {
        fmt.Println(it.Next().Value) // 输出 1 2 3
    }
}

扩展场景 2:分页遍历大数据集
需求:每次获取N条数据的迭代器

type PageIterator struct {
    dataSource func(int, int) []*Book // 模拟数据源函数
    pageSize   int
    currentPage int
    offset     int
}

func (p *PageIterator) HasNext() bool {
    return len(p.dataSource(p.currentPage, p.pageSize)) > 0
}

func (p *PageIterator) Next() []*Book {
    chunk := p.dataSource(p.currentPage, p.pageSize)
    p.currentPage++
    return chunk
}

// 模拟数据库分页查询
func mockDB(page, size int) []*Book {
    // 实际场景中这里会连接数据库
    return []*Book{{Title: fmt.Sprintf("Book-%d", page)}}
}

func main() {
    pager := &PageIterator{
        dataSource: mockDB,
        pageSize:   10,
    }
    
    for pager.HasNext() {
        books := pager.Next()
        fmt.Println(books) // 分批次获取数据
    }
}

扩展场景 3:并发安全迭代器
需求:支持多线程安全遍历

type SafeIterator struct {
    mutex    sync.Mutex
    iterator *BookIterator
}

func (s *SafeIterator) HasNext() bool {
    s.mutex.Lock()
    defer s.mutex.Unlock()
    return s.iterator.HasNext()
}

func (s *SafeIterator) Next() *Book {
    s.mutex.Lock()
    defer s.mutex.Unlock()
    return s.iterator.Next()
}

func main() {
    collection := &BookCollection{/* 初始化数据 */}
    
    safeIter := &SafeIterator{
        iterator: collection.CreateIterator().(*BookIterator),
    }
    
    // 可安全用于goroutine
    go func() {
        for safeIter.HasNext() {
            fmt.Println(safeIter.Next())
        }
    }()
}

迭代器模式的优势总结

  • 解耦遍历逻辑:将数据存储与遍历操作分离
  • 支持多种遍历方式:正序/逆序/过滤/分页等
  • 简化集合接口:集合只需提供创建迭代器的方法
  • 延迟加载支持:特别适合大数据场景的分批加载
  • 线程安全扩展:通过封装实现并发控制

这些扩展场景展示了迭代器模式在不同业务需求下的适应能力,适用于文件系统遍历、数据库查询结果处理、网络数据流处理等复杂场景。


http://www.niftyadmin.cn/n/5864999.html

相关文章

Sui链开发:技术架构与生态实践深度解析(2025年最新进展)

一、Sui链的核心技术架构 1. 并行执行与对象模型 ui采用对象导向模型&#xff0c;将链上资产&#xff08;如NFT、代币&#xff09;视为独立对象&#xff0c;通过并行处理机制实现高吞吐量。每个对象的交易可独立验证&#xff0c;无需全局共识&#xff0c;显著提升处理效率&…

HTTP代理与HTTPS代理的区别及HTTPS的工作原理

在互联网世界中&#xff0c;数据的传输与访问安全性是用户和企业共同关注的焦点。HTTP和HTTPS代理作为两种常用的网络协议代理&#xff0c;它们在工作原理和应用场景上存在显著区别。本文将深入浅出地解析HTTP代理与HTTPS代理的区别&#xff0c;并简明扼要地介绍HTTPS的工作原理…

DeepSeek开源周首日:发布大模型加速核心技术可变长度高效FlashMLA 加持H800算力解码性能狂飙升至3000GB/s

FlashMLA的核心技术特性包括对BF16精度的全面支持&#xff0c;以及采用块大小为64的页式键值缓存&#xff08;Paged KV Cache&#xff09;系统&#xff0c;实现更精确的内存管理。在性能表现方面&#xff0c;基于CUDA12.6平台&#xff0c;FlashMLA在H800SXM5GPU上创下了显著成绩…

大模型在术后认知功能障碍预测及临床方案制定中的应用研究

目录 一、引言 1.1 研究背景与意义 1.2 研究目的与方法 1.3 研究创新点 二、术后认知功能障碍概述 2.1 定义与表现 2.2 危害与影响 2.3 发病机制与相关因素 三、大模型技术原理与应用现状 3.1 大模型技术原理 3.2 大模型在医疗领域的应用 四、基于大模型的术后认知…

Web刷题之PolarDN(中等)

1.到底给不给flag呢 代码审计 一道典型的php变量覆盖漏洞 相关知识 什么是变量覆盖漏洞 自定义的参数值替换原有变量值的情况称为变量覆盖漏洞 经常导致变量覆盖漏洞场景有&#xff1a;$$使用不当&#xff0c;extract()函数使用不当&#xff0c;parse_str()函数使用不当&…

npm : 无法加载文件 E:\ProgramFiles\Nodejs\npm.ps1,因为在此系统上禁止运行脚本。

这个错误是因为 Windows 系统的 PowerShell 执行策略 限制了脚本的运行。默认情况下&#xff0c;PowerShell 的执行策略是 Restricted&#xff0c;即禁止运行任何脚本。以下是解决该问题的步骤&#xff1a; 1. 检查当前执行策略 打开 PowerShell&#xff08;管理员权限&#x…

人工智能、机器学习、深度学习和大语言模型之间的关系

人工智能&#xff08;AI&#xff09;、机器学习&#xff08;ML&#xff09;、深度学习&#xff08;DL&#xff09;和大语言模型&#xff08;LLM&#xff09;之间是逐层包含且技术递进的关系&#xff0c;具体如下&#xff1a; 1. 层级关系 人工智能&#xff08;AI&#xff09;…

通过恒定带宽服务器调度改进时间敏感网络(TSN)流量整形

论文标题 英文标题&#xff1a;Improving TSN Traffic Shaping with Constant Bandwidth Server Scheduling 中文标题&#xff1a;通过恒定带宽服务器调度改进时间敏感网络&#xff08;TSN&#xff09;流量整形 作者信息 作者&#xff1a;Benjamin van Seggelen 指导教师&am…