设计模式 | 迭代器模式

迭代器模式(Iterator Pattern)是行为型设计模式中的集合遍历专家,它提供一种方法顺序访问聚合对象的元素而不暴露其底层表示。这种模式将遍历逻辑从集合中解耦,使集合结构和遍历算法能独立演化。本文将深入剖析迭代器模式的核心思想、实现技巧及其在C++中的高效实践。


为什么需要迭代器模式?

在软件开发中,我们经常需要处理各种集合对象:

  • 数组、链表、树、图等数据结构

  • 数据库查询结果集

  • 文件系统中的目录结构

  • 社交网络的用户关系链

直接操作集合内部结构会导致:
暴露实现细节:客户端需要了解集合内部结构
遍历逻辑重复:相同遍历逻辑散落在代码各处
紧耦合:算法与具体集合实现绑定
扩展困难:新增遍历方式需修改集合类

迭代器模式通过提供统一的遍历接口解决了这些问题。


迭代器模式的核心概念

模式结构解析
[聚合对象] → [迭代器接口] ← [具体迭代器]
    ▲               ▲
    │               │
[具体聚合对象]   [客户端]
关键角色定义
  1. 迭代器接口(Iterator)

    • 定义访问和遍历元素的接口

    • 包含next()current()isDone()等方法

  2. 具体迭代器(Concrete Iterator)

    • 实现迭代器接口

    • 跟踪当前遍历位置

  3. 聚合接口(Aggregate)

    • 定义创建迭代器的接口

    • 通常包含createIterator()方法

  4. 具体聚合对象(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;
}

迭代器模式的五大优势

  1. 统一遍历接口

    // 不同集合使用相同的遍历方式
    printAggregate(array);
    printAggregate(list);
    printAggregate(tree);
  2. 隐藏内部实现

    // 客户端不知道集合内部结构
    while (!it->isDone()) {
        auto item = it->currentItem();
        it->next();
    }
  3. 支持多种遍历

    // 二叉树前序迭代器
    class PreOrderIterator : public Iterator<T> { ... };
  4. 并行遍历支持

    auto it1 = collection.createIterator();
    auto it2 = collection.createIterator();
  5. 延迟加载

    // 数据库迭代器按需加载数据
    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_;
};

总结

迭代器模式是处理集合遍历的优雅解决方案,它通过:

  • 抽象遍历:分离集合结构与遍历算法

  • 统一接口:提供一致的遍历方式

  • 多种实现:支持不同遍历策略

  • 解耦设计:客户端不依赖具体集合

适用场景

  • 需要统一遍历不同集合

  • 需要支持多种遍历方式

  • 需要隐藏集合内部结构

  • 需要并行遍历同一集合

"迭代器模式不是简单的循环,而是将遍历提升为设计元素。它是封装集合访问的优雅抽象。" — 设计模式实践者

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值