1.定义
提供一种顺序访问集合内元素的方法,但不暴露集合内部实现细节的设计模式,属于行为型设计模式.
迭代器模式将数据的存储和遍历相分离,存储交给聚合类,遍历交给迭代器类,如果需要对新的集合进行顺序遍历,只需要扩展新的迭代器类和聚合类。
2.迭代器模式的相关组成
抽象聚合类
提供一个创建迭代器对象的接口、添加元素接口、删除元素接口
具体聚合类
根据存储元素方式的不同,重写创建迭代器接口,返回自己对应的迭代器
并重写添加元素和删除元素接口
具体聚合类和具体迭代器类是互相对应的
抽象迭代器类
提供一种可以查看集合中是否有下一个元素和走到集合的下一个元素位置的接口
具体迭代器类
为具体聚合类实现对应的接口,因为不同聚合类内部存储元素的方式可能不同
3.代码实现
#include <iostream>
#include <string>
#include <vector>
#include <list>
using namespace std;
//学生类
//集合中存储的元素类型
class Student
{
public:
string _name; //姓名
string _stuNo; //学号
string _college; //学院
public:
Student(const string& name, const string& stuNo, const string& college)
:_name(name)
, _stuNo(stuNo)
, _college(college)
{}
//展示学生信息
void showInfo()
{
cout << "姓名: " << _name << "\t学号: " << _stuNo << "\t学院: " << _college << endl;
}
};
//抽象迭代器
class Iterator
{
public:
//下一个位置是否有元素
virtual bool hasNext() = 0;
//返回当前元素,并且走到下一个位置
virtual Student next() = 0;
};
//计算机学院迭代器
class ComputerIterator : public Iterator
{
private:
vector<Student> _info; //迭代器访问的数据集合
int _curPos; //当前访问的下标位置
public:
ComputerIterator(const vector<Student>& info)
:_info(info)
, _curPos(0)
{}
//下一个位置是否有元素
virtual bool hasNext()
{
return _curPos < _info.size();
}
//返回当前元素,并且走到下一个位置
virtual Student next()
{
Student curStu = _info[_curPos++];
return curStu;
}
};
//体育学院迭代器
//因为内部存储数据的容器是list
//为了不使用STL提供的迭代器,所以遍历的顺序是从链表的头部到尾部
//每次访问元素之后会删除链表头部元素
class SportIterator : public Iterator
{
private:
list<Student> _info; //迭代器访问的数据集合
public:
//下一个位置是否有元素
virtual bool hasNext()
{
return !_info.empty();
}
//返回当前元素,并且走到下一个位置
virtual Student next()
{
Student front = _info.front();
_info.pop_front();
return front;
}
SportIterator(const list<Student>& info)
:_info(info)
{}
};
//抽象聚合类
class Aggregate
{
public:
//添加学生信息
virtual void addStudent(const Student& stu) = 0;
//删除学生信息
virtual void deleteStudent(const Student& stu) = 0;
//创建迭代器
virtual Iterator* createIterator() = 0;
};
//计算机学院聚合类
class ComputerAggregate : public Aggregate
{
private:
vector<Student> _info; //学生信息数据管理器
public:
//添加学生信息
virtual void addStudent(const Student& stu)
{
_info.emplace_back(stu);
}
//删除学生信息
virtual void deleteStudent(const Student& stu)
{
auto it = _info.begin();
while (it != _info.end())
{
if (it->_name == stu._name && it->_stuNo == stu._stuNo && it->_college == stu._college)
{
break;
}
++it;
}
_info.erase(it);
}
//创建迭代器
virtual Iterator* createIterator()
{
return new ComputerIterator(_info);
}
};
//体育学院聚合类
class SportAggregate : public Aggregate
{
private:
list<Student> _info; //存储学生对象的集合
public:
//添加学生信息
virtual void addStudent(const Student& stu)
{
_info.push_back(stu);
}
//删除学生信息
virtual void deleteStudent(const Student& stu)
{
auto it = _info.begin();
while (it != _info.end())
{
if (it->_name == stu._name && it->_stuNo == stu._stuNo && it->_college == stu._college)
{
break;
}
++it;
}
_info.erase(it);
}
//创建迭代器
virtual Iterator* createIterator()
{
return new SportIterator(_info);
}
};
//计算机学院测试
void test_College()
{
Aggregate* computerCollege = new ComputerAggregate();
computerCollege->addStudent(Student("索隆", "11", "计算机"));
computerCollege->addStudent(Student("红发香克斯", "12", "计算机"));
computerCollege->addStudent(Student("路飞", "13", "计算机"));
computerCollege->addStudent(Student("娜美", "14", "计算机"));
computerCollege->addStudent(Student("山治", "15", "计算机"));
Iterator* it = computerCollege->createIterator();
cout << "************* 计算机学院 **************" << endl;
while (it->hasNext())
{
it->next().showInfo();
}
}
//体育学院测试
void test_Sport()
{
Aggregate* sportCollege = new SportAggregate();
sportCollege->addStudent(Student("白胡子", "0", "体育"));
sportCollege->addStudent(Student("雷利", "1", "体育"));
sportCollege->addStudent(Student("罗杰", "2", "体育"));
sportCollege->addStudent(Student("凯多", "3", "体育"));
sportCollege->addStudent(Student("黑胡子", "4", "体育"));
sportCollege->addStudent(Student("BigMom", "5", "体育"));
Iterator* it = sportCollege->createIterator();
cout << "************* 体育学院 **************" << endl;
while (it->hasNext())
{
it->next().showInfo();
}
}
int main()
{
test_College();
cout << "\n\n\n\n" << endl;
test_Sport();
return 0;
}
运行结果演示

4.优缺点
优点:
符合开闭原则,如果需要对新的元素集合进行遍历,只需要添加新的具体聚合类和具体迭代器类;
支持在同一个集合上采用不同的遍历方式;
缺点:
对新集合进行遍历需要增加一个具体聚合类和一个具体迭代器类,造成类的个数增加
本文介绍了迭代器模式,它提供了一种不暴露内部细节的顺序访问集合元素的方式。通过分离数据存储与遍历,迭代器模式允许在不修改原有聚合类的情况下扩展新的遍历方式。代码示例展示了如何在计算机学院和体育学院的学生信息管理中使用迭代器,分别实现了基于`vector`和`list`的迭代。
692

被折叠的 条评论
为什么被折叠?



