• 迭代器模式(Iterator)


    参考:

    迭代器设计模式 (refactoringguru.cn)

    [design-patterns-cpp/Iterator.cpp at master · JakubVojvoda/design-patterns-cpp · GitHub

    一、什么是迭代器模式

    提供一种方法,顺序访问一个聚合对象中(集合)的各个元素,而又不暴露该对象的内部表示。

    在这里插入图片描述

    二、实现

    在这里插入图片描述

    迭代器(Iterator)模式包含以下主要角色:

    1、抽象聚合类(Aggregate)角色:也有人把它叫集合。抽象聚合类用于存储对象,并定义创建相应迭代器对象的接口,声明一个createIterator方法用于创建一个迭代器对象。
    2、具体聚合类(Concrete Aggregate)角色:具体聚合类实现了创建相应迭代器的接口,实现了在聚合类中声明的createIterator方法,该方法返回一个与该具体聚合对应的具体迭代器ConcreteIterator实例。
    3、抽象迭代器(Iterator)角色:抽象迭代器定义了访问和遍历元素的接口,一般声明如下方法:用于获取第一个元素的first(),用于访问下一个元素的next(),用于判断是否还有下一个元素的hasNext(),用于获取当前元素的currentItem(),在其子类中将实现这些方法。
    4、具体迭代器(Concrete Iterator)角色:具体迭代器实现了抽象迭代器接口,完成对聚合对象的遍历,同时在对聚合进行遍历时跟踪其当前对象。

    /*
     * C++ Design Patterns: Iterator
     * Author: Jakub Vojvoda [github.com/JakubVojvoda]
     * 2016
     *
     * Source code is licensed under MIT License
     * (for more details see LICENSE)
     *
     */
    
    #include 
    #include 
    #include 
    
    class Iterator;
    class ConcreteAggregate;
    
    /*
     * Aggregate
     * defines an interface for aggregates and it decouples your
     * client from the implementation of your collection of objects
     */
    class Aggregate
    {
    public:
      virtual ~Aggregate() {}
      
      virtual Iterator *createIterator() = 0;
      // ...
    };
    
    /*
     * Concrete Aggregate
     * has a collection of objects and implements the method
     * that returns an Iterator for its collection
     *
     */
    class ConcreteAggregate : public Aggregate
    {
    public:
      ConcreteAggregate( const unsigned int size )
      {
        list = new int[size]();
        count = size;
      }
      
      ~ConcreteAggregate()
      {
        delete[] list;
      }
      
      Iterator *createIterator();
      
      unsigned int size() const
      {
        return count;
      }
      
      int at( unsigned int index )
      {
        return list[ index ];
      }
      // ...
    
    private:
      int *list;
      unsigned int count;
      // ...
    };
    
    /*
     * Iterator
     * provides the interface that all iterators must implement and
     * a set of methods for traversing over elements
     */
    class Iterator
    {
    public:
      virtual ~Iterator() { /* ... */ }
      
      virtual void first() = 0;
      virtual void next() = 0;
      virtual bool isDone() const = 0;
      virtual int currentItem() const = 0;
      // ...
    };
    
    /*
     * Concrete Iterator
     * implements the interface and is responsible for managing
     * the current position of the iterator
     */
    class ConcreteIterator : public Iterator
    {
    public:
      ConcreteIterator( ConcreteAggregate *l ) :
        list( l ), index( 0 ) {}
      
      ~ConcreteIterator() {}
      
      void first()
      {
        index = 0;
      }
      
      void next()
      {
        index++;
      }
      
      bool isDone() const
      {
        return ( index >= list->size() );
      }
      
      int currentItem() const
      {
        if ( isDone() )
        {
          return -1;
        }
        return list->at(index);
      }
      // ...
    
    private:
      ConcreteAggregate *list;
      unsigned int index;
      // ...
    };
    
    Iterator *ConcreteAggregate::createIterator()
    {
      return new ConcreteIterator( this );
    }
    
    
    int main()
    {
      unsigned int size = 5;
      ConcreteAggregate list = ConcreteAggregate( size );
      
      Iterator *it = list.createIterator();
      for ( ; !it->isDone(); it->next())
      {
        std::cout << "Item value: " << it->currentItem() << std::endl;
      }
      
      delete it;
      return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151

    Note

    以上使用运行时多态实现的迭代器,以C++中已经用模板替换。当遍历次数较多时,由于访问虚函数表次数过多会导致性能下降,而编译时多态正好弥补了这一问题。

    三、优缺点

    优点

    • 使用该模式可以减少程序中重复的遍历代码。
    • 如果你希望代码能够遍历不同的甚至是无法预知的数据结构,可以使用迭代器模式。

    缺点

    • 对于某些特殊集合, 使用迭代器可能比直接遍历的效率低。
  • 相关阅读:
    java.util.ConcurrentModificationException: null(已解决)
    什么是网络存储服务器
    免杀Backdoor-factory
    本地存储(LocalStorage)、会话存储(Session)和 Cookie 三者之间的区别
    0015Java程序设计-springboot美食网站
    王学岗-编译出运行的文件
    C# 将音频PCM数据封装成wav文件
    2023电工杯数学建模B题完整模型代码【原创首发】
    背后的力量 | 提升医疗服务“速度“和“温度” 华云数据助力上海国际医学中心加速智慧医院建设
    Nginx主配置文件和监控模块VTS
  • 原文地址:https://blog.csdn.net/I_just_smile/article/details/128087314