迭代器模式深度指南:遍历集合的艺术
迭代器模式是一种行为设计模式,提供了一种顺序访问集合元素的方法,而无需暴露集合的底层表示。
为什么需要迭代器模式?
直接遍历暴露了内部结构:
for i in range(len(collection)):
print(collection[i])
问题:
- 耦合性高:代码与特定数据结构绑定
- 缺乏灵活性:数据结构改变,遍历代码也要修改
- 无法复用:每种数据结构都需要独立的遍历逻辑
迭代器模式的核心结构
| 角色 | 职责 |
|---|---|
| Iterator | 定义访问和遍历元素的接口 |
| ConcreteIterator | 实现迭代器接口,记录当前位置 |
| Aggregate | 定义创建迭代器对象的接口 |
| ConcreteAggregate | 实现创建迭代器接口 |
Python 实现
基础迭代器
class Book:
def __init__(self, title, author):
self.title = title
self.author = author
class LibraryIterator:
def __init__(self, books):
self._books = books
self._position = 0
def __iter__(self):
return self
def __next__(self):
if self._position >= len(self._books):
raise StopIteration
book = self._books[self._position]
self._position += 1
return book
class Library:
def __init__(self):
self._books = []
def add_book(self, book):
self._books.append(book)
def __iter__(self):
return LibraryIterator(self._books)
# 使用
library = Library()
library.add_book(Book("设计模式", "GoF"))
library.add_book(Book("重构", "Martin Fowler"))
for book in library:
print(f"{book.title} - {book.author}")
生成器实现
class Library:
def __init__(self):
self._books = []
def add_book(self, book):
self._books.append(book)
def __iter__(self):
for book in self._books:
yield book
实际应用场景
1. 惰性加载分页数据
class LazyPageIterator:
def __init__(self, fetch_func, page_size=10):
self._fetch_func = fetch_func
self._page_size = page_size
self._current_page = 0
self._current_data = []
self._position = 0
self._exhausted = False
def __iter__(self):
return self
def __next__(self):
if self._position >= len(self._current_data):
if self._exhausted:
raise StopIteration
self._current_page += 1
self._current_data = self._fetch_func(
self._current_page, self._page_size
)
if not self._current_data:
self._exhausted = True
raise StopIteration
self._position = 0
item = self._current_data[self._position]
self._position += 1
return item
2. 组合模式深度优先遍历
class FileSystemNode:
def __init__(self, name):
self.name = name
self.children = []
def add(self, node):
self.children.append(node)
class CompositeIterator:
def __init__(self, node):
self._stack = [node]
def __iter__(self):
return self
def __next__(self):
if not self._stack:
raise StopIteration
node = self._stack.pop(0)
for child in reversed(node.children):
self._stack.insert(0, child)
return node.name
迭代器模式 vs for 循环
| 特性 | 迭代器模式 | for 循环 |
|---|---|---|
| 内存效率 | 惰性加载,按需获取 | 一次性加载 |
| 状态管理 | 自动记录当前位置 | 需要手动管理索引 |
| 解耦 | 与数据结构解耦 | 依赖数据结构 |
Python 迭代器协议
class MyIterator:
def __init__(self, data):
self._data = data
self._index = 0
def __iter__(self):
return self
def __next__(self):
if self._index >= len(self._data):
raise StopIteration
result = self._data[self._index]
self._index += 1
return result
最佳实践
- 优先使用生成器:
yield关键字让迭代器更简洁 - 遵循单一职责:迭代器只负责遍历
- 支持多种遍历方式:前向、反向、过滤等
- 文档化遍历行为:明确遍历顺序和终止条件
总结
迭代器模式:
- 解耦数据结构和遍历逻辑
- 简化客户端代码
- 提高可维护性和可测试性
- 支持惰性加载和流式处理
理解这一模式能帮助我们更好地使用语言特性,在需要时自定义遍历逻辑,设计更优雅的API。
参考资料
- 《设计模式:可复用面向对象软件的基础》
- Fluent Python - Luciano Ramalho
Comments
No comments yet. Start the discussion.