迭代器模式(Iterator Pattern)是行为型设计模式中的集合遍历专家,它提供一种方法顺序访问聚合对象的元素而不暴露其底层表示。这种模式将遍历逻辑从集合中解耦,使集合结构和遍历算法能独立演化。本文将深入剖析迭代器模式的核心思想、实现技巧及其在C++中的高效实践。
为什么需要迭代器模式?
在软件开发中,我们经常需要处理各种集合对象:
-
数组、链表、树、图等数据结构
-
数据库查询结果集
-
文件系统中的目录结构
-
社交网络的用户关系链
直接操作集合内部结构会导致:
暴露实现细节:客户端需要了解集合内部结构
遍历逻辑重复:相同遍历逻辑散落在代码各处
紧耦合:算法与具体集合实现绑定
扩展困难:新增遍历方式需修改集合类
迭代器模式通过提供统一的遍历接口解决了这些问题。
迭代器模式的核心概念
模式结构解析
[聚合对象] → [迭代器接口] ← [具体迭代器]
▲ ▲
│ │
[具体聚合对象] [客户端]
关键角色定义
-
迭代器接口(Iterator)
-
定义访问和遍历元素的接口
-
包含
next()
,current()
,isDone()
等方法
-
-
具体迭代器(Concrete Iterator)
-
实现迭代器接口
-
跟踪当前遍历位置
-
-
聚合接口(Aggregate)
-
定义创建迭代器的接口
-
通常包含
createIterator()
方法
-
-
具体聚合对象(Concrete Aggregate)
-
实现聚合接口
-
返回具体迭代器实例
-
C++实现:多容器统一遍历系统
实现支持数组、链表和二叉树的迭代器:
#include <iostream>
#include <vector>
#include <list>
#include <stack>
#include <memory>
// ================= 迭代器接口 =================
template <typename T>
class Iterator {
public:
virtual ~Iterator() = default;
virtual void first() = 0;
virtual void next() = 0;
virtual bool isDone() const = 0;
virtual T currentItem() const = 0;
};
// ================= 具体迭代器:数组迭代器 =================
template <typename T>
class ArrayIterator : public Iterator<T> {
public:
explicit ArrayIterator(const std::vector<T>& data)
: data_(data), index_(0) {}
void first() override { index_ = 0; }
void next() override {
if (!isDone()) ++index_;
}
bool isDone() const override {
return index_ >= data_.size();
}
T currentItem() const override {
if (isDone()) throw std::out_of_range("迭代器越界");
return data_[index_];
}
private:
const std::vector<T>& data_;
size_t index_;
};
// ================= 具体迭代器:链表迭代器 =================
template <typename T>
class ListIterator : public Iterator<T> {
public:
explicit ListIterator(const std::list<T>& data)
: data_(data), it_(data_.begin()) {}
void first() override { it_ = data_.begin(); }
void next() override {
if (!isDone()) ++it_;
}
bool isDone() const override {
return it_ == data_.end();
}
T currentItem() const override {
if (isDone()) throw std::out_of_range("迭代器越界");
return *it_;
}
private:
const std::list<T>& data_;
typename std::list<T>::const_iterator it_;
};
// ================= 二叉树节点 =================
template <typename T>
struct TreeNode {
T data;
std::unique_ptr<TreeNode> left;
std::unique_ptr<TreeNode> right;
explicit TreeNode(T val) : data(std::move(val)) {}
};
// ================= 具体迭代器:中序二叉树迭代器 =================
template <typename T>
class InOrderIterator : public Iterator<T> {
public:
explicit InOrderIterator(const TreeNode<T>* root) {
populateStack(root);
if (!stack_.empty()) current_ = stack_.top();
}
void first() override {
// 中序遍历第一个元素已在栈顶
}
void next() override {
if (isDone()) return;
stack_.pop();
if (!stack_.empty()) {
current_ = stack_.top();
} else {
current_ = nullptr;
}
}
bool isDone() const override {
return stack_.empty();
}
T currentItem() const override {
if (isDone()) throw std::out_of_range("迭代器越界");
return current_->data;
}
private:
void populateStack(const TreeNode<T>* node) {
if (!node) return;
// 模拟递归中序遍历
std::stack<const TreeNode<T>*> temp;
const TreeNode<T>* current = node;
while (current || !temp.empty()) {
while (current) {
temp.push(current);
current = current->left.get();
}
current = temp.top();
temp.pop();
stack_.push(current);
current = current->right.get();
}
}
std::stack<const TreeNode<T>*> stack_;
const TreeNode<T>* current_ = nullptr;
};
// ================= 聚合接口 =================
template <typename T>
class Aggregate {
public:
virtual ~Aggregate() = default;
virtual std::unique_ptr<Iterator<T>> createIterator() const = 0;
virtual size_t size() const = 0;
};
// ================= 具体聚合:动态数组 =================
template <typename T>
class DynamicArray : public Aggregate<T> {
public:
void add(T item) { data_.push_back(std::move(item)); }
std::unique_ptr<Iterator<T>> createIterator() const override {
return std::make_unique<ArrayIterator<T>>(data_);
}
size_t size() const override { return data_.size(); }
T& operator[](size_t index) { return data_[index]; }
const T& operator[](size_t index) const { return data_[index]; }
private:
std::vector<T> data_;
};
// ================= 具体聚合:链表 =================
template <typename T>
class LinkedList : public Aggregate<T> {
public:
void add(T item) { data_.push_back(std::move(item)); }
std::unique_ptr<Iterator<T>> createIterator() const override {
return std::make_unique<ListIterator<T>>(data_);
}
size_t size() const override { return data_.size(); }
private:
std::list<T> data_;
};
// ================= 具体聚合:二叉树 =================
template <typename T>
class BinaryTree : public Aggregate<T> {
public:
void add(T value) {
insert(root_, std::move(value));
}
std::unique_ptr<Iterator<T>> createIterator() const override {
return std::make_unique<InOrderIterator<T>>(root_.get());
}
size_t size() const override {
return countNodes(root_.get());
}
private:
void insert(std::unique_ptr<TreeNode<T>>& node, T value) {
if (!node) {
node = std::make_unique<TreeNode<T>>(std::move(value));
return;
}
if (value < node->data) {
insert(node->left, std::move(value));
} else {
insert(node->right, std::move(value));
}
}
size_t countNodes(const TreeNode<T>* node) const {
if (!node) return 0;
return 1 + countNodes(node->left.get()) + countNodes(node->right.get());
}
std::unique_ptr<TreeNode<T>> root_;
};
// ================= 客户端代码 =================
template <typename T>
void printAggregate(const Aggregate<T>& agg) {
auto it = agg.createIterator();
std::cout << "集合内容 (" << agg.size() << " 个元素): ";
for (it->first(); !it->isDone(); it->next()) {
std::cout << it->currentItem() << " ";
}
std::cout << "\n\n";
}
int main() {
// 数组集合
DynamicArray<int> array;
for (int i = 1; i <= 5; ++i) array.add(i);
printAggregate(array);
// 链表集合
LinkedList<std::string> list;
list.add("Apple");
list.add("Banana");
list.add("Cherry");
printAggregate(list);
// 二叉树集合
BinaryTree<int> tree;
for (int i : {5, 3, 7, 2, 4, 6, 8}) tree.add(i);
printAggregate(tree);
// 自定义遍历
auto treeIt = tree.createIterator();
std::cout << "查找大于5的元素: ";
for (treeIt->first(); !treeIt->isDone(); treeIt->next()) {
if (treeIt->currentItem() > 5) {
std::cout << treeIt->currentItem() << " ";
}
}
return 0;
}
迭代器模式的五大优势
-
统一遍历接口
// 不同集合使用相同的遍历方式 printAggregate(array); printAggregate(list); printAggregate(tree);
-
隐藏内部实现
// 客户端不知道集合内部结构 while (!it->isDone()) { auto item = it->currentItem(); it->next(); }
-
支持多种遍历
// 二叉树前序迭代器 class PreOrderIterator : public Iterator<T> { ... };
-
并行遍历支持
auto it1 = collection.createIterator(); auto it2 = collection.createIterator();
-
延迟加载
// 数据库迭代器按需加载数据 class DatabaseIterator : public Iterator<Record> { Record currentItem() const { if (!loaded) loadCurrentRecord(); return currentRecord; } };
迭代器模式的高级应用
1. 过滤迭代器
template <typename T, typename Predicate>
class FilterIterator : public Iterator<T> {
public:
FilterIterator(std::unique_ptr<Iterator<T>> source, Predicate pred)
: source_(std::move(source)), pred_(pred) {
skipToNextValid();
}
void first() override {
source_->first();
skipToNextValid();
}
void next() override {
source_->next();
skipToNextValid();
}
T currentItem() const override {
return source_->currentItem();
}
bool isDone() const override {
return source_->isDone();
}
private:
void skipToNextValid() {
while (!source_->isDone() && !pred_(source_->currentItem())) {
source_->next();
}
}
std::unique_ptr<Iterator<T>> source_;
Predicate pred_;
};
// 使用
auto baseIt = list.createIterator();
auto evenIt = std::make_unique<FilterIterator<int>>(
std::move(baseIt), [](int x) { return x % 2 == 0; });
2. 线程安全迭代器
template <typename T>
class ThreadSafeIterator : public Iterator<T> {
public:
explicit ThreadSafeIterator(Iterator<T>& inner)
: inner_(inner), mutex_(std::make_shared<std::mutex>()) {}
void first() override {
std::lock_guard lock(*mutex_);
inner_.first();
}
void next() override {
std::lock_guard lock(*mutex_);
inner_.next();
}
// ... 其他方法类似实现
private:
Iterator<T>& inner_;
std::shared_ptr<std::mutex> mutex_;
};
3. 组合迭代器
class CompositeIterator : public Iterator<Component> {
public:
explicit CompositeIterator(Component& component) {
stack_.push(component.createIterator());
}
void first() override {
while (!stack_.empty()) stack_.pop();
// 重新初始化...
}
void next() override {
auto& current = *stack_.top();
if (!current.isDone()) {
auto item = current.currentItem();
if (auto composite = dynamic_cast<Composite*>(item)) {
stack_.push(composite->createIterator());
}
} else {
stack_.pop();
if (!stack_.empty()) stack_.top()->next();
}
}
// ... 其他方法
private:
std::stack<std::unique_ptr<Iterator<Component>>> stack_;
};
应用场景
1. STL风格迭代器
class VectorIterator {
public:
explicit VectorIterator(std::vector<int>& vec)
: vec_(vec), idx_(0) {}
bool hasNext() const {
return idx_ < vec_.size();
}
int next() {
return vec_[idx_++];
}
private:
std::vector<int>& vec_;
size_t idx_;
};
// 使用
VectorIterator it(vec);
while (it.hasNext()) {
std::cout << it.next() << " ";
}
2. 文件系统遍历
class DirectoryIterator : public Iterator<File> {
public:
explicit DirectoryIterator(const std::string& path) {
dir_ = opendir(path.c_str());
next();
}
~DirectoryIterator() {
if (dir_) closedir(dir_);
}
void first() override {
rewinddir(dir_);
next();
}
void next() override {
current_.reset();
while (auto entry = readdir(dir_)) {
if (entry->d_name[0] != '.') {
current_ = std::make_unique<File>(entry->d_name);
break;
}
}
}
bool isDone() const override {
return current_ == nullptr;
}
File currentItem() const override {
return *current_;
}
private:
DIR* dir_;
std::unique_ptr<File> current_;
};
3. 数据库结果集遍历
class DatabaseResultIterator : public Iterator<Record> {
public:
explicit DatabaseResultIterator(DatabaseResult& result)
: result_(result) {}
void first() override {
result_.seek(0);
}
void next() override {
result_.next();
}
bool isDone() const override {
return result_.isEnd();
}
Record currentItem() const override {
return result_.current();
}
private:
DatabaseResult& result_;
};
迭代器模式与其他模式的关系
模式 | 关系 | 区别 |
---|---|---|
组合模式 | 常共同使用遍历组合结构 | 组合关注结构,迭代器关注遍历 |
工厂方法 | 聚合对象创建对应迭代器 | 工厂方法用于创建对象 |
备忘录 | 保存迭代器状态 | 实现回滚功能 |
访问者 | 通过迭代器遍历元素应用访问者 | 访问者定义元素操作 |
组合使用示例:
// 组合模式 + 迭代器模式
class Composite : public Component {
std::unique_ptr<Iterator<Component>> createIterator() override {
return std::make_unique<CompositeIterator>(children_);
}
};
迭代器模式的挑战与解决方案
挑战 | 解决方案 |
---|---|
遍历状态复杂 | 使用备忘录保存状态 |
并发修改问题 | 实现版本控制或快照迭代器 |
多种遍历算法 | 策略模式选择迭代算法 |
资源管理 | RAII管理资源 |
快照迭代器示例:
class SnapshotIterator : public Iterator<T> {
public:
explicit SnapshotIterator(const Aggregate<T>& agg)
: snapshot_(agg.clone()) {
it_ = snapshot_->createIterator();
}
// 委托给快照的迭代器
void first() override { it_->first(); }
void next() override { it_->next(); }
bool isDone() const override { return it_->isDone(); }
T currentItem() const override { return it_->currentItem(); }
private:
std::unique_ptr<Aggregate<T>> snapshot_;
std::unique_ptr<Iterator<T>> it_;
};
总结
迭代器模式是处理集合遍历的优雅解决方案,它通过:
-
抽象遍历:分离集合结构与遍历算法
-
统一接口:提供一致的遍历方式
-
多种实现:支持不同遍历策略
-
解耦设计:客户端不依赖具体集合
适用场景:
-
需要统一遍历不同集合
-
需要支持多种遍历方式
-
需要隐藏集合内部结构
-
需要并行遍历同一集合
"迭代器模式不是简单的循环,而是将遍历提升为设计元素。它是封装集合访问的优雅抽象。" — 设计模式实践者