C++设计模式之行为型模式:迭代器模式(Iterator) - 详解

行为型设计模式的一种,它提供了一种就是迭代器模式(Iterator)顺序访问聚合对象元素的方法,而无需暴露聚合对象的内部结构。这种模式将遍历逻辑与聚合对象分离,使遍历操作更加灵活,同时支持对同一聚合对象进行多种不同的遍历。

一、核心思想与角色

迭代器模式的核心是“分离聚合与遍历”,通过引入迭代器对象统一遍历接口,使客户端可以用相同的方式遍历不同的聚合结构。其核心角色如下:

角色名称核心职责
抽象迭代器(Iterator)定义遍历聚合对象的接口,包含hasNext()(是否有下一个元素)和next()(获取下一个元素)等方法。
具体迭代器(ConcreteIterator)实现抽象迭代器接口,记录当前遍历位置,搞定实际的遍历逻辑。
抽象聚合(Aggregate)定义创建迭代器的接口(如createIterator()),声明聚合对象的基本操作。
具体聚合(ConcreteAggregate)实现抽象聚合接口,存储元素集合,返回具体迭代器实例。
客户端(Client)通过抽象迭代器接口遍历聚合对象,无需关心聚合的具体类型和内部结构。

核心思想:将聚合对象的遍历逻辑封装到迭代器中,客户端通过迭代器接口访问聚合元素,使聚合与遍历解耦,同时支持多种遍历方式(如正序、逆序)。

二、实现示例(自定义集合与迭代器)

假设我们需要实现一个自定义的动态数组(DynamicArray)和链表(LinkedList),并为它们提供统一的遍历接口。使用迭代器模式可使客户端用相同的方式遍历两种不同的聚合结构:

#include <iostream>
  #include <string>
    // 1. 抽象迭代器
    template <typename T>
      class Iterator {
      public:
      virtual bool hasNext() const = 0; // 是否有下一个元素
      virtual T next() = 0;             // 获取下一个元素
      virtual ~Iterator() = default;
      };
      // 2. 抽象聚合
      template <typename T>
        class Aggregate {
        public:
        virtual Iterator<T>* createIterator() = 0; // 创建迭代器
          virtual void add(const T& item) = 0;       // 添加元素
          virtual int size() const = 0;              // 获取元素数量
          virtual ~Aggregate() = default;
          };
          // 3. 具体聚合1:动态数组
          template <typename T>
            class DynamicArray : public Aggregate<T> {
              private:
              T* elements;   // 元素数组
              int capacity;  // 容量
              int count;     // 当前元素数量
              // 扩容
              void resize() {
              capacity *= 2;
              T* newElements = new T[capacity];
              for (int i = 0; i < count; ++i) {
              newElements[i] = elements[i];
              }
              delete[] elements;
              elements = newElements;
              }
              public:
              DynamicArray(int initialCapacity = 4)
              : capacity(initialCapacity), count(0) {
              elements = new T[capacity];
              }
              // 添加元素
              void add(const T& item) override {
              if (count >= capacity) {
              resize();
              }
              elements[count++] = item;
              }
              // 获取指定位置元素(供迭代器使用)
              T get(int index) const {
              if (index >= 0 && index < count) {
              return elements[index];
              }
              throw std::out_of_range("索引越界");
              }
              int size() const override {
              return count;
              }
              // 创建数组迭代器
              Iterator<T>* createIterator() override;
                ~DynamicArray() {
                delete[] elements;
                }
                };
                // 3. 具体迭代器1:数组迭代器
                template <typename T>
                  class ArrayIterator : public Iterator<T> {
                    private:
                    DynamicArray<T>* array; // 关联的数组
                      int currentIndex;       // 当前索引
                      public:
                      ArrayIterator(DynamicArray<T>* arr) : array(arr), currentIndex(0) {}
                        bool hasNext() const override {
                        return currentIndex < array->size();
                          }
                          T next() override {
                          if (hasNext()) {
                          return array->get(currentIndex++);
                          }
                          throw std::out_of_range("没有更多元素");
                          }
                          };
                          // 为DynamicArray实现createIterator(需在ArrayIterator定义后)
                          template <typename T>
                            Iterator<T>* DynamicArray<T>::createIterator() {
                              return new ArrayIterator<T>(this);
                                }
                                // 3. 具体聚合2:链表
                                template <typename T>
                                  class LinkedList : public Aggregate<T> {
                                    private:
                                    // 链表节点
                                    struct Node {
                                    T data;
                                    Node* next;
                                    Node(const T& d) : data(d), next(nullptr) {}
                                    };
                                    Node* head;  // 头节点
                                    int count;   // 元素数量
                                    public:
                                    LinkedList() : head(nullptr), count(0) {}
                                    void add(const T& item) override {
                                    Node* newNode = new Node(item);
                                    if (!head) {
                                    head = newNode;
                                    } else {
                                    Node* current = head;
                                    while (current->next) {
                                    current = current->next;
                                    }
                                    current->next = newNode;
                                    }
                                    count++;
                                    }
                                    int size() const override {
                                    return count;
                                    }
                                    // 获取头节点(供迭代器使用)
                                    Node* getHead() const {
                                    return head;
                                    }
                                    // 创建链表迭代器
                                    Iterator<T>* createIterator() override;
                                      ~LinkedList() {
                                      Node* current = head;
                                      while (current) {
                                      Node* next = current->next;
                                      delete current;
                                      current = next;
                                      }
                                      }
                                      };
                                      // 3. 具体迭代器2:链表迭代器
                                      template <typename T>
                                        class ListIterator : public Iterator<T> {
                                          private:
                                          typename LinkedList<T>::Node* current; // 当前节点(注意typename声明嵌套类型)
                                            public:
                                            ListIterator(LinkedList<T>* list) : current(list->getHead()) {}
                                              bool hasNext() const override {
                                              return current != nullptr;
                                              }
                                              T next() override {
                                              if (hasNext()) {
                                              T data = current->data;
                                              current = current->next;
                                              return data;
                                              }
                                              throw std::out_of_range("没有更多元素");
                                              }
                                              };
                                              // 为LinkedList实现createIterator
                                              template <typename T>
                                                Iterator<T>* LinkedList<T>::createIterator() {
                                                  return new ListIterator<T>(this);
                                                    }
                                                    // 客户端代码:统一遍历不同聚合
                                                    template <typename T>
                                                      void printAggregate(Aggregate<T>* aggregate) {
                                                        Iterator<T>* iterator = aggregate->createIterator();
                                                          std::cout << "元素列表:";
                                                          while (iterator->hasNext()) {
                                                          std::cout << iterator->next() << " ";
                                                            }
                                                            std::cout << std::endl;
                                                            delete iterator;
                                                            }
                                                            int main() {
                                                            // 测试动态数组
                                                            Aggregate<int>* array = new DynamicArray<int>();
                                                              array->add(10);
                                                              array->add(20);
                                                              array->add(30);
                                                              std::cout << "遍历动态数组:" << std::endl;
                                                              printAggregate(array);
                                                              // 测试链表
                                                              Aggregate<std::string>* list = new LinkedList<std::string>();
                                                                list->add("Hello");
                                                                list->add("World");
                                                                list->add("Iterator");
                                                                std::cout << "\n遍历链表:" << std::endl;
                                                                printAggregate(list);
                                                                // 释放资源
                                                                delete array;
                                                                delete list;
                                                                return 0;
                                                                }

三、代码解析

  1. 抽象迭代器(Iterator)
    定义了模板接口,包含hasNext()(判断是否有下一个元素)和next()(获取下一个元素)方法,为所有具体迭代器提供统一规范。

  2. 抽象聚合(Aggregate)
    定义了模板接口,包含createIterator()(创建迭代器)、add()(添加元素)和size()(获取大小)方法,所有聚合类都需实现这些接口。

  3. 具体聚合与迭代器

    • 动态数组(DynamicArray):内部用数组存储元素,实现了add()等方法,createIterator()返回ArrayIterator实例。
    • 数组迭代器(ArrayIterator):记录当前索引(currentIndex),通过hasNext()判断是否越界,next()返回当前元素并递增索引。
    • 链表(LinkedList):内部用节点链表存储元素,createIterator()返回ListIterator实例。
    • 链表迭代器(ListIterator):记录当前节点(current),hasNext()判断节点是否为空,next()返回当前节点数据并移动到下一个节点。
  4. 客户端使用
    客户端通过printAggregate()函数统一遍历不同聚合(数组和链表),该函数仅依赖抽象的AggregateIterator接口,无需知道具体聚合类型,体现了“依赖倒置原则”。

四、核心优势与适用场景

优势
  1. 解耦聚合与遍历:聚合对象无需关心遍历逻辑,迭代器专注于遍历,符合单一职责原则。
  2. 统一遍历接口:客户端可用相同的代码遍历不同的聚合结构(如数组、链表、树),简化了客户端代码。
  3. 支持多种遍历:可为同一聚合提供多种迭代器(如正序、逆序、过滤迭代器),客户端按需选择。
  4. 隐藏内部结构:迭代器屏蔽了聚合对象的内部实现(如数组的索引、链表的节点),保护了聚合的封装性。
适用场景
  1. 需要遍历麻烦聚合结构:如自定义集合类(数组、链表、哈希表)、树形结构(二叉树、目录树)。
  2. 希望统一遍历接口:当系统中有多种聚合类型,且希望客户端用一致的方式遍历时(如STL中的begin()/end())。
  3. 要求多种遍历方式:如对集合同时支持正序遍历、逆序遍历、按条件过滤遍历。

五、与其他模式的区别

模式核心差异点
迭代器模式专注于聚合对象的遍历,分离遍历逻辑与聚合结构,献出统一遍历接口。
访问者模式利用访问者对象为不同元素添加新执行,不关注遍历,侧重管理扩展。
组合模式构建树形结构表示“部分-整体”关系,可与迭代器模式结合利用(如遍历组合对象)。
工厂模式迭代器的创建过程可通过工厂模式实现(如createIterator()本质是工厂方法)。

六、实践建议

  1. 使用模板实现通用迭代器:如示例中使用C++模板,使迭代器可帮助任意数据类型,提高复用性。
  2. 实现双向迭代器:对于需要反向遍历的场景,可扩展迭代器接口,添加hasPrevious()previous()方法。
  3. 支撑迭代器失效处理否失效(如STL中的迭代器失效规则)。就是:当聚合对象被修改(如添加/删除元素)时,需考虑迭代器
  4. 结合C++11迭代器特性:在实际开发中,可遵循C++标准库的迭代器设计(如begin()/end()++运算符重载),提高代码兼容性。

迭代器模式的核心价值在于“标准化遍历执行,隔离聚合与遍历不可或缺的设计选择。就是”。它依据统一的迭代器接口,使客户端可以忽略聚合对象的内部结构,用一致的方式遍历各种集合,同时为扩展新的聚合类型或遍历方式提供了便利。在设计自定义集合类或需要统一遍历逻辑的场景中,迭代器模式

posted @ 2025-11-10 11:07  yxysuanfa  阅读(3)  评论(0)    收藏  举报