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. 复杂数据结构遍历
// 二叉树迭代器实现
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 遍历过程控制 | 迭代器实例化 |
七、实现建议
- 接口隔离:定义细粒度的迭代器接口
- 资源释放:实现Close方法释放数据库连接等资源
- 缓存优化:对大型数据集实现分页加载机制
- 错误处理:增加Error方法返回遍历错误信息
八、典型应用
- 集合框架:Go的slice/map遍历扩展
- 数据管道:ETL处理中的数据流控制
- 游戏引擎:场景对象遍历与碰撞检测
- 机器学习:批量数据加载与预处理
通过迭代器模式,可以实现数据遍历逻辑与业务逻辑的彻底解耦。在Go语言中,结合channel和goroutine可创建支持并行处理的流式迭代器,适用于大数据处理场景。实际开发中应注意迭代器生命周期管理,避免资源泄漏问题。