迭代器模式(Iterator Pattern)

C++ 迭代器模式(Iterator Pattern)

一、模式基础概述

1.1 定义

迭代器模式属于行为型设计模式 ,提供统一遍历接口,以顺序方式访问聚合容器内所有元素,全程不对外暴露容器内部存储结构、数据组织形式。将遍历逻辑与容器存储逻辑解耦,遵循单一职责原则。

1.2 核心思想

剥离集合自身的遍历行为,单独封装迭代器对象负责元素访问;客户端仅通过标准接口遍历数据,无需关心底层是数组、链表、树形等存储结构。

1.3 设计原则

  1. 单一职责:容器负责数据存储增删,迭代器负责遍历访问
  2. 迪米特法则:隐藏内部结构,降低外部与容器耦合度
  3. 开闭原则:新增遍历方式只需新增迭代器,不改动容器代码

二、核心组成角色

角色名称 核心职责 C++ 实现形式
抽象迭代器 Iterator 声明通用遍历接口,判断是否存在下一元素、获取当前元素 抽象模板基类,纯虚函数定义接口
具体迭代器 ConcreteIterator 实现遍历接口,记录遍历游标位置,关联聚合容器,完成实际遍历 继承抽象迭代器,重写遍历方法
抽象聚合容器 Aggregate 定义创建迭代器的统一接口,规范容器基础操作 抽象基类,声明创建迭代器函数
具体聚合容器 ConcreteAggregate 存储实际元素,实现创建迭代器方法,提供元素查询、新增能力 继承抽象聚合,内部维护数据集合
客户端 Client 通过迭代器遍历元素,调用标准接口完成访问 业务调用代码、主函数

三、模式运行流程

  1. 客户端创建具体聚合容器,并向容器添加业务元素
  2. 调用容器接口生成专属迭代器实例
  3. 客户端循环调用迭代器判断接口,校验是否还有未遍历元素
  4. 存在元素则获取当前元素,并移动遍历游标
  5. 遍历结束后终止访问,整个过程不直接操作容器内部数据

四、经典业务示例:书架书籍遍历

cpp 复制代码
#include <iostream>
#include <vector>
#include <string>
#include <memory>

// 元素实体:书籍
class Book
{
private:
    std::string bookName;
public:
    Book(std::string name) : bookName(std::move(name)) {}
    std::string getName() const
    {
        return bookName;
    }
};

// 抽象迭代器模板
template<typename T>
class Iterator
{
public:
    virtual ~Iterator() = default;
    virtual bool hasNext() const = 0;
    virtual T next() = 0;
};

// 抽象聚合容器模板
template<typename T>
class Aggregate
{
public:
    virtual ~Aggregate() = default;
    virtual std::unique_ptr<Iterator<T>> createIterator() const = 0;
    virtual void addElement(const T& elem) = 0;
    virtual int getSize() const = 0;
    virtual T getElement(int index) const = 0;
};

// 具体容器:书架
class BookShelf : public Aggregate<Book>
{
private:
    std::vector<Book> bookList;
public:
    void addElement(const Book& elem) override
    {
        bookList.push_back(elem);
    }

    int getSize() const override
    {
        return bookList.size();
    }

    Book getElement(int index) const override
    {
        return bookList[index];
    }

    std::unique_ptr<Iterator<Book>> createIterator() const override;
};

// 具体迭代器:书架迭代器
class BookShelfIterator : public Iterator<Book>
{
private:
    const BookShelf* shelf;
    int currentIndex;
public:
    BookShelfIterator(const BookShelf* shelfObj)
        : shelf(shelfObj), currentIndex(0) {}

    bool hasNext() const override
    {
        return currentIndex < shelf->getSize();
    }

    Book next() override
    {
        return shelf->getElement(currentIndex++);
    }
};

// 容器绑定迭代器
std::unique_ptr<Iterator<Book>> BookShelf::createIterator() const
{
    return std::make_unique<BookShelfIterator>(this);
}

// 客户端调用
int main()
{
    BookShelf shelf;
    shelf.addElement(Book("C++设计模式"));
    shelf.addElement(Book("数据结构与算法"));
    shelf.addElement(Book("Linux编程实战"));

    auto iterator = shelf.createIterator();
    std::cout << "书架内书籍列表:\n";
    while (iterator->hasNext())
    {
        Book book = iterator->next();
        std::cout << book.getName() << std::endl;
    }
    return 0;
}

五、通用模板示例:自定义任务容器遍历

cpp 复制代码
#include <iostream>
#include <vector>
#include <memory>

// 通用抽象迭代器
template<typename T>
class BaseIterator
{
public:
    virtual ~BaseIterator() = default;
    virtual bool existNext() = 0;
    virtual T fetchNext() = 0;
};

// 通用抽象容器
template<typename T>
class BaseContainer
{
public:
    virtual ~BaseContainer() = default;
    virtual std::unique_ptr<BaseIterator<T>> getIterator() = 0;
    virtual void append(const T& data) = 0;
    virtual size_t getLength() const = 0;
    virtual T getData(size_t idx) const = 0;
};

// 线性存储容器
template<typename T>
class LinearContainer : public BaseContainer<T>
{
private:
    std::vector<T> dataArr;
public:
    void append(const T& data) override
    {
        dataArr.push_back(data);
    }

    size_t getLength() const override
    {
        return dataArr.size();
    }

    T getData(size_t idx) const override
    {
        return dataArr[idx];
    }

    std::unique_ptr<BaseIterator<T>> getIterator() override;
};

// 线性容器迭代器
template<typename T>
class LinearIterator : public BaseIterator<T>
{
private:
    LinearContainer<T>* container;
    size_t cursor;
public:
    LinearIterator(LinearContainer<T>* con) : container(con), cursor(0) {}

    bool existNext() override
    {
        return cursor < container->getLength();
    }

    T fetchNext() override
    {
        return container->getData(cursor++);
    }
};

template<typename T>
std::unique_ptr<BaseIterator<T>> LinearContainer<T>::getIterator()
{
    return std::make_unique<LinearIterator<T>>(this);
}

// 测试使用
int main()
{
    LinearContainer<std::string> taskContainer;
    taskContainer.append("路径规划");
    taskContainer.append("环境检测");
    taskContainer.append("设备自检");

    auto iter = taskContainer.getIterator();
    std::cout << "\n机器人任务清单:\n";
    while (iter->existNext())
    {
        std::cout << iter->fetchNext() << std::endl;
    }
    return 0;
}

六、迭代器分类说明

  1. 外部迭代器
    客户端主动控制遍历启停、游标移动,日常开发最常用。
  2. 内部迭代器
    迭代器自身完成全部遍历逻辑,客户端仅发起遍历请求。
  3. 正向迭代器
    仅支持从头部向尾部单向遍历。
  4. 双向迭代器
    可前后移动游标,支持正反遍历元素。
  5. 随机访问迭代器
    支持下标取值、游标跳跃访问,访问效率最高。

七、与C++ STL迭代器关联

STL容器遍历是迭代器模式工业化落地实现

  1. begin()end() 等同于创建迭代器对象
  2. ++-- 运算符实现游标移动
  3. * 解引用运算符获取容器元素
  4. 统一遍历接口,vector、list、map可复用遍历代码
cpp 复制代码
#include <iostream>
#include <vector>
int main()
{
    std::vector<int> numVec = {10,20,30,40};
    // STL标准迭代器用法
    for (auto it = numVec.begin(); it != numVec.end(); ++it)
    {
        std::cout << *it << " ";
    }
    return 0;
}

八、模式优缺点

8.1 优点

  1. 统一遍历接口,适配多种异构容器,遍历代码可复用
  2. 屏蔽容器底层存储细节,提升数据安全性
  3. 存储与遍历职责拆分,代码结构清晰易维护
  4. 可同时创建多个迭代器,并行遍历同一容器
  5. 灵活扩展遍历方式,正序、倒序、过滤遍历互不影响

8.2 缺点

  1. 每新增一种容器,需配套编写对应迭代器类,类数量增加
  2. 极简小型集合使用该模式,存在代码冗余、过度设计
  3. 遍历过程中修改容器结构,容易引发迭代器失效问题

九、适用业务场景

  1. 项目存在多种不同存储结构的集合,需要统一遍历方式
  2. 要求隐藏容器内部数据组织,禁止外部直接访问底层结构
  3. 同一集合需要提供多种遍历规则、访问顺序
  4. 分离数据存储与遍历逻辑,降低模块间耦合
  5. 任务队列、数据集、地图节点、日志条目遍历场景

十、相近模式区分

模式 核心作用 侧重点
迭代器模式 统一访问集合元素 容器遍历、隐藏内部结构
组合模式 统一处理树形整体与节点 层级递归遍历对象
访问者模式 在不修改类前提下新增操作 对元素执行自定义业务操作

十一、C++工程编码规范

  1. 使用std::unique_ptr管理迭代器实例,自动回收内存
  2. 迭代器仅做元素访问,不修改容器内部数据与结构
  3. 遍历周期内避免增删元素,防止迭代器失效崩溃
  4. 常规业务优先使用STL原生迭代器,自定义特殊容器再手写迭代器
  5. 抽象接口精简通用,保证不同迭代器调用规则一致

十二、模式总结

迭代器模式核心是访问分离、结构隐藏、接口统一

通过独立迭代器接管遍历逻辑,让容器专注数据存储,客户端以通用方式读取元素,无需感知底层实现。该模式是C++容器体系的基础设计思想,广泛应用于数据遍历、任务处理、集合管理等业务场景,有效简化多容器兼容开发成本。

相关推荐
Benszen1 小时前
K8S存储管理
容器·rpc·kubernetes
KaMeidebaby2 小时前
卡梅德生物技术快报|免疫共沉淀 - Co-IP 实验在转录因子 ATF3/Smad4 蛋白互作研究中的应用实例解析
网络·人工智能·网络协议·tcp/ip·其他·算法·新浪微博
nnsix3 小时前
设计模式 - 迭代器模式 笔记
笔记·设计模式·迭代器模式
Lsland..3 小时前
MCP协议AI时代的HTTP
人工智能·网络协议·http
IT大白鼠12 小时前
RSTP协议原理与配置详解:快速生成树技术的深度解析
网络·网络协议
笨鸟飞不快17 小时前
从一次网络请求出发,彻底搞懂事件循环、I/O 多路复用与响应式编程
网络协议
缪懿20 小时前
网络层和数据链路层中的常见协议解析
网络·网络协议·java-ee
田里的水稻21 小时前
OE_永久配置网络_linux系统终端命令行ip_setting
人工智能·网络协议·机器人·运维开发