元素码农
基础
UML建模
数据结构
算法
设计模式
网络
TCP/IP协议
HTTPS安全机制
WebSocket实时通信
数据库
sqlite
postgresql
clickhouse
后端
rust
go
java
php
mysql
redis
mongodb
etcd
nats
zincsearch
前端
浏览器
javascript
typescript
vue3
react
游戏
unity
unreal
C++
C#
Lua
App
android
ios
flutter
react-native
安全
Web安全
测试
软件测试
自动化测试 - Playwright
人工智能
Python
langChain
langGraph
运维
linux
docker
工具
git
svn
🌞
🌙
目录
▶
设计原则
单一职责原则
开闭原则
里氏替换原则
依赖倒置原则
接口隔离原则
迪米特法则
▶
创建型模式
工厂方法模式
抽象工厂
单例模式
建造者模式
原型模式
▶
结构型模式
适配器模式
装饰器模式
代理模式
外观模式
组合模式
桥接模式
享元模式
▶
行为型模式
策略模式
观察者模式
命令模式
模板方法模式
状态模式
责任链模式
迭代器模式
中介者模式
访问者模式
备忘录模式
解释器模式
发布时间:
2025-03-21 15:22
↑
☰
# 迭代器模式 ## 概述 迭代器模式(Iterator Pattern)是一种行为型设计模式,它提供一种方法顺序访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部表示。迭代器模式将遍历集合的责任从集合中分离出来,放到迭代器对象中。 ## 问题场景 在软件开发中,我们经常会遇到以下场景: 1. 需要访问一个集合对象的内容,但不暴露其内部结构 2. 需要支持对集合对象的多种遍历方式 3. 需要为遍历不同的集合结构提供一个统一的接口 ## 解决方案 迭代器模式通过以下方式解决这些问题: ```mermaid classDiagram class Iterator { <<interface>> +hasNext() +next() +current() } class ConcreteIterator { -collection -position +hasNext() +next() +current() } class Aggregate { <<interface>> +createIterator() } class ConcreteAggregate { -items +createIterator() } Iterator <|.. ConcreteIterator Aggregate <|.. ConcreteAggregate ConcreteIterator --> ConcreteAggregate ``` 主要角色: 1. 迭代器(Iterator): 定义访问和遍历元素的接口 2. 具体迭代器(ConcreteIterator): 实现迭代器接口 3. 聚合(Aggregate): 定义创建迭代器对象的接口 4. 具体聚合(ConcreteAggregate): 实现创建迭代器的接口 ## 代码示例 ### 1. 基本实现 ```go // Iterator 迭代器接口 type Iterator interface { HasNext() bool Next() interface{} Current() interface{} } // Aggregate 聚合接口 type Aggregate interface { CreateIterator() Iterator } // ConcreteAggregate 具体聚合 type ConcreteAggregate struct { items []interface{} } func NewConcreteAggregate(items []interface{}) *ConcreteAggregate { return &ConcreteAggregate{items: items} } func (c *ConcreteAggregate) CreateIterator() Iterator { return NewConcreteIterator(c) } // ConcreteIterator 具体迭代器 type ConcreteIterator struct { aggregate *ConcreteAggregate position int } func NewConcreteIterator(aggregate *ConcreteAggregate) Iterator { return &ConcreteIterator{ aggregate: aggregate, position: 0, } } func (c *ConcreteIterator) HasNext() bool { return c.position < len(c.aggregate.items) } func (c *ConcreteIterator) Next() interface{} { if c.HasNext() { item := c.aggregate.items[c.position] c.position++ return item } return nil } func (c *ConcreteIterator) Current() interface{} { if c.position < len(c.aggregate.items) { return c.aggregate.items[c.position] } return nil } ``` ### 2. 实际应用示例 ```go // 以音乐播放列表为例 // Song 歌曲 type Song struct { name string artist string } // PlaylistIterator 播放列表迭代器接口 type PlaylistIterator interface { HasNext() bool Next() *Song Current() *Song } // Playlist 播放列表接口 type Playlist interface { CreateIterator() PlaylistIterator Add(song *Song) Remove(song *Song) } // MusicPlaylist 音乐播放列表 type MusicPlaylist struct { songs []*Song } func NewMusicPlaylist() *MusicPlaylist { return &MusicPlaylist{ songs: make([]*Song, 0), } } func (p *MusicPlaylist) CreateIterator() PlaylistIterator { return NewMusicPlaylistIterator(p) } func (p *MusicPlaylist) Add(song *Song) { p.songs = append(p.songs, song) } func (p *MusicPlaylist) Remove(song *Song) { for i, s := range p.songs { if s == song { p.songs = append(p.songs[:i], p.songs[i+1:]...) break } } } // MusicPlaylistIterator 音乐播放列表迭代器 type MusicPlaylistIterator struct { playlist *MusicPlaylist position int } func NewMusicPlaylistIterator(playlist *MusicPlaylist) PlaylistIterator { return &MusicPlaylistIterator{ playlist: playlist, position: 0, } } func (i *MusicPlaylistIterator) HasNext() bool { return i.position < len(i.playlist.songs) } func (i *MusicPlaylistIterator) Next() *Song { if i.HasNext() { song := i.playlist.songs[i.position] i.position++ return song } return nil } func (i *MusicPlaylistIterator) Current() *Song { if i.position < len(i.playlist.songs) { return i.playlist.songs[i.position] } return nil } // 使用示例 func main() { // 创建播放列表 playlist := NewMusicPlaylist() // 添加歌曲 playlist.Add(&Song{name: "Song 1", artist: "Artist 1"}) playlist.Add(&Song{name: "Song 2", artist: "Artist 2"}) playlist.Add(&Song{name: "Song 3", artist: "Artist 3"}) // 使用迭代器遍历播放列表 iterator := playlist.CreateIterator() for iterator.HasNext() { song := iterator.Next() fmt.Printf("Playing: %s by %s\n", song.name, song.artist) } } ``` ## 适用场景 1. 访问聚合对象内容 - 不需要暴露内部结构 - 需要统一的遍历接口 2. 多种遍历方式 - 支持不同的遍历算法 - 可以切换遍历策略 3. 简化聚合类 - 将遍历责任分离 - 使聚合类更专注 ## 优缺点 ### 优点 1. 单一职责原则 - 将集合的遍历行为分离 - 简化集合的接口 2. 支持多种遍历方式 - 可以定义多个迭代器 - 实现不同的遍历算法 3. 简化客户端代码 - 统一的遍历接口 - 不需要了解集合内部 ### 缺点 1. 增加类的数量 - 需要额外的迭代器类 - 增加系统复杂度 2. 可能存在性能问题 - 迭代器保存额外的状态 - 可能占用额外的内存 ## 实现要点 1. 迭代器接口设计 - 定义遍历操作 - 考虑遍历方向 2. 迭代器状态管理 - 维护遍历位置 - 处理无效状态 3. 集合接口设计 - 创建迭代器方法 - 管理元素操作 ## 相关模式 1. 组合模式 - 经常和迭代器一起使用 - 遍历复杂结构 2. 工厂方法模式 - 创建迭代器对象 - 封装迭代器创建 3. 备忘录模式 - 保存迭代器状态 - 实现回溯功能 ## 总结 迭代器模式是一种用于遍历集合对象的行为型设计模式,它的核心价值在于: 1. 封装变化 - 将遍历算法封装 - 使集合和遍历分离 2. 统一接口 - 提供统一的访问方式 - 简化客户端代码 3. 扩展性 - 易于添加新的遍历方式 - 不影响现有代码 在实际开发中,迭代器模式常用于需要遍历复杂数据结构的场景,如遍历树形结构、遍历数据库结果集等。使用迭代器模式可以使代码更加清晰、易于维护,同时也提供了良好的扩展性。