Golang学习笔记_42——迭代器模式

发布于:2025-03-04 ⋅ 阅读:(14) ⋅ 点赞:(0)

Golang学习笔记_39——策略模式
Golang学习笔记_40——模版方法模式
Golang学习笔记_41——观察者模式



一、核心概念

1. 定义

迭代器模式是一种行为型设计模式,提供顺序访问聚合对象元素的方法,无需暴露其内部结构。其核心特点包括:

  • 解耦遍历逻辑:将遍历算法与聚合对象分离
  • 统一访问接口:为不同数据结构提供一致的遍历方式
  • 多态迭代:支持多种遍历策略(正序/倒序/过滤等)

2. 解决的问题

  • 数据遍历标准化:为异构数据结构提供统一遍历接口
  • 封装复杂性:隐藏列表、树、图等复杂结构的实现细节
  • 并行遍历:支持多个独立的遍历过程同时进行

3. 核心角色

角色 作用
Iterator 定义遍历接口(HasNext/Next)
ConcreteIterator 实现特定数据结构的遍历逻辑
Aggregate 定义创建迭代器的方法
ConcreteAggregate 实现具体聚合对象并返回关联迭代器

4. 类图

迭代器模式类图

@startuml
interface Iterator {
    + HasNext() bool
    + Next() interface{}
}

interface Aggregate {
    + CreateIterator() Iterator
}

class BookIterator {
    - books: []*Book
    - position: int
}

class BookCollection {
    - books: []*Book
}

Iterator <|-- BookIterator
Aggregate <|-- BookCollection
BookCollection *-- BookIterator
@enduml

二、特点分析

优点

  1. 单一职责原则:分离集合管理与遍历算法
  2. 开闭原则:新增迭代类型无需修改聚合对象
  3. 并行遍历:支持多迭代器独立工作

缺点

  1. 性能损耗:间接访问元素带来额外开销
  2. 过度设计:简单集合使用迭代器可能增加复杂度
  3. 状态管理:需要维护遍历位置信息

三、适用场景

1. 复杂数据结构遍历

// 二叉树迭代器实现
type TreeNode struct {
    Value int
    Left  *TreeNode
    Right *TreeNode
}

type TreeIterator struct {
    stack []*TreeNode
}

func (t *TreeIterator) HasNext() bool {
    return len(t.stack) > 0
}

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

2. 数据库结果集处理

// SQL查询结果迭代器
type SQLResultIterator struct {
    rows *sql.Rows
}

func (s *SQLResultIterator) HasNext() bool {
    return s.rows.Next()
}

func (s *SQLResultIterator) Next() map[string]interface{} {
    columns, _ := s.rows.Columns()
    values := make([]interface{}, len(columns))
    valuePtrs := make([]interface{}, len(columns))
    
    for i := range columns {
        valuePtrs[i] = &values[i]
    }
    
    s.rows.Scan(valuePtrs...)
    result := make(map[string]interface{})
    for i, col := range columns {
        result[col] = values[i]
    }
    return result
}

3. 文件系统遍历

// 目录迭代器实现
type DirIterator struct {
    files []fs.DirEntry
    index int
}

func (d *DirIterator) HasNext() bool {
    return d.index < len(d.files)
}

func (d *DirIterator) Next() fs.DirEntry {
    if !d.HasNext() {
        return nil
    }
    file := d.files[d.index]
    d.index++
    return file
}

四、Go语言实现示例

示例类图

完整实现代码

package iterator_demo

import "fmt"

// Iterator interface
type Iterator interface {
	HasNext() bool
	Next() interface{}
}

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

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

type Book struct {
	Title  string
	Author string
}

func (bc *BookCollection) CreateIterator() Iterator {
	return &BookIterator{
		books:    bc.books,
		position: 0,
	}
}

type BookIterator struct {
	books    []*Book
	position int
}

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

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

func test() {
	book1 := &Book{Title: "Book 1", Author: "Author 1"}
	book2 := &Book{Title: "Book 2", Author: "Author 2"}
	book3 := &Book{Title: "Book 3", Author: "Author 3"}
	collection := &BookCollection{
		books: []*Book{book1, book2, book3},
	}
	iterator := collection.CreateIterator()
	for iterator.HasNext() {
		book := iterator.Next().(*Book)
		fmt.Printf("书名:%s,作者:%s\n", book.Title, book.Author)
	}
}

执行结果

=== RUN   Test_test
书名:Book 1,作者:Author 1
书名:Book 2,作者:Author 2
书名:Book 3,作者:Author 3
--- PASS: Test_test (0.00s)
PASS

五、高级应用

1. 过滤迭代器

type FilterIterator struct {
	source Iterator
	filter func(interface{}) bool
}

func (f *FilterIterator) HasNext() bool {
	for f.source.HasNext() {
		if f.filter(f.source.Next()) {
			f.source.(*BookIterator).position-- // 回退指针
			return true
		}
	}
	return false
}

func (f *FilterIterator) Next() interface{} {
	return f.source.Next()
}

// 使用示例
filter := &FilterIterator{
	source: collection.CreateIterator(),
	filter: func(item interface{}) bool {
		return item.(*Book).Author == "王争"
	},
}

2. 并发安全迭代器

type SafeIterator struct {
	mu      sync.Mutex
	inner   Iterator
}

func (s *SafeIterator) HasNext() bool {
	s.mu.Lock()
	defer s.mu.Unlock()
	return s.inner.HasNext()
}

func (s *SafeIterator) Next() interface{} {
	s.mu.Lock()
	defer s.mu.Unlock()
	return s.inner.Next()
}

六、与其他模式对比

模式 核心区别 典型场景
访问者模式 关注元素操作 vs 关注遍历过程 复杂结构数据统计
组合模式 树形结构处理 vs 遍历算法封装 文件系统目录遍历
工厂模式 对象创建 vs 遍历过程控制 迭代器实例化

七、实现建议

  1. 接口隔离:定义细粒度的迭代器接口
  2. 资源释放:实现Close方法释放数据库连接等资源
  3. 缓存优化:对大型数据集实现分页加载机制
  4. 错误处理:增加Error方法返回遍历错误信息

八、典型应用

  1. 集合框架:Go的slice/map遍历扩展
  2. 数据管道:ETL处理中的数据流控制
  3. 游戏引擎:场景对象遍历与碰撞检测
  4. 机器学习:批量数据加载与预处理

通过迭代器模式,可以实现数据遍历逻辑与业务逻辑的彻底解耦。在Go语言中,结合channel和goroutine可创建支持并行处理的流式迭代器,适用于大数据处理场景。实际开发中应注意迭代器生命周期管理,避免资源泄漏问题。


网站公告

今日签到

点亮在社区的每一天
去签到