
意图:
提供一种方法顺序访问一个聚合对象中各个元素, 而又无须暴露该对象的内部表示。
主要解决:
不同的方式来遍历整个整合对象。
何时使用:
遍历一个聚合对象。
如何解决:
把在元素之间游走的责任交给迭代器,而不是聚合对象。
关键代码:
定义接口:hasNext, next。
应用实例:
C++中的 iterator。
优点:
1、它支持以不同的方式遍历一个聚合对象。
2、迭代器简化了聚合类。
3、在同一个聚合上可以有多个遍历。
4、在迭代器模式中,增加新的聚合类和迭代器类都很方便,无须修改原有代码。
缺点:
由于迭代器模式将存储数据和遍历数据的职责分离,增加新的聚合类需要对应增加新的迭代器类,类的个数成对增加,这在一定程度上增加了系统的复杂性。
使用场景:
1、访问一个聚合对象的内容而无须暴露它的内部表示。
2、需要为聚合对象提供多种遍历方式。
3、为遍历不同的聚合结构提供一个统一的接口。
注意事项:
迭代器模式就是分离了集合对象的遍历行为,抽象出一个迭代器类来负责,这样既可以做到不暴露集合的内部结构,又可让外部代码透明地访问集合内部的数据。
通过聚合类中items作为存储数组
要想遍历这个items就需要通过迭代器类进行遍历
核心代码是重载操作符[]来实现
templateclass Iterator; template class ConcreteIterator; template class Aggregate; template class ConcreteAggregate; // 聚集抽象类 template class Aggregate{ public: // 创建一个迭代器 virtual Iterator *CreateIterator(){}; }; // 具体聚集类 template class ConcreteAggregate : public Aggregate { private: vector items; // 声明一个泛型变量, 用于存放聚合对象 public: // 创建一个自己的迭代器 Iterator *CreateIterator(){ return new ConcreteIterator (this); } // 返回聚集总数 int Size(){ return items.size(); } // [] 重载 T &operator[] (int index){ cout << "使用重载" << index << endl; return items[index]; } void push_back(T val){ items.push_back(val); } void print(){ cout << "当前聚类里面的内容有: " << endl; for(auto & a : items){ cout << a << " "; }cout<< "/n" << endl; } }; // 迭代器模式 // 迭代器抽象类 template // l类似于Java中的object, 也就是所有类的祖宗 class Iterator{ public: // 用于定义得到开始, 下一个, 是否结尾, 当前对象的方法的统一接口 virtual T First(){}; virtual T Next(){}; virtual bool IsDone(){}; virtual T CurrentItem(){}; }; // 具体迭代器 template class ConcreteIterator : public Iterator { private: ConcreteAggregate *aggregate = nullptr; // 定义了一个具体的聚集对象 int current = 0; public: // 初始化时 具体的聚集对象传入 ConcreteIterator(ConcreteAggregate *aggregate) : aggregate(aggregate){ cout << "当前聚类中长度有: " << this->aggregate->Size() << endl; } // 得到第一个聚集对象, 由于传过来的是指针, 需要通过(*指针)在通过[] 重载运算符访问iter里面对应的对象 T First(){ return (*aggregate)[0]; } // 得到当前的 T CurrentItem(){ return (*aggregate)[current]; } // 得到下一个 T Next(){ T ret = ""; current++; if(current < aggregate->Size()){ ret = (*aggregate)[current]; } return ret; } bool IsDone(){ return current >= aggregate->Size() ? true : false; } }; void test(){ ConcreteAggregate *a = new ConcreteAggregate (); // 10个乘客的公交车, 聚集对象 a->push_back("大鸟"); a->push_back("算法"); a->push_back("放到"); a->push_back("奇偶偶"); a->print(); Iterator *i = new ConcreteIterator (a); // 售票员出厂, 开始迭代所有人 string item = i->First(); cout << "first: " << item << endl; cout << "currentItem: " << i->CurrentItem() << endl; cout<< "----------------" << endl; while(!i->IsDone()){ cout << i->CurrentItem() << endl; i->Next(); } delete a; a = nullptr; delete i; i = nullptr; }
输出
前聚类里面的内容有: 大鸟 算法 放到 奇偶偶 /n 当前聚类中长度有: 4 使用重载0 first: 大鸟 currentItem: 使用重载0 大鸟 ---------------- 使用重载0 大鸟 使用重载1 使用重载1 算法 使用重载2 使用重载2 放到 使用重载3 使用重载3 奇偶偶3. 应用
上一篇 《深入理解Java虚拟机》(第二版)学习2:垃圾收集算法
下一篇 EdgeX(9): 使用最新的 edgex2.0干啥,硬件是一方面,重要的另外一方面是软件的匹配,也要做好相关的开发,新的API V2接口学习,实现设备的注册、服务的注册