Iterator mode (C + + implementation)

1. Definitions

A design pattern that provides a method to access elements in a collection in sequence, but does not expose the implementation details inside the collection, belongs to behavioral design pattern
The iterator mode separates the storage and traversal of data. The storage is handed over to the aggregation class, and the traversal is handed over to the iterator class. If you need to traverse the new collection sequentially, you only need to extend the new iterator class and aggregation class.

2. Related components of iterator pattern

Abstract aggregate class

Provide an interface for creating iterator object, adding element interface and deleting element interface

Concrete aggregate class

According to the different ways of storing elements, rewrite the interface of creating iterators and return their corresponding iterators
And override the interface for adding and deleting elements
Concrete aggregate classes and concrete iterator classes correspond to each other

Abstract iterator class

Provides an interface that can check whether there is a next element in the collection and go to the next element location of the collection

Concrete iterator

Implement the corresponding interface for specific aggregate classes, because different aggregate classes may store elements in different ways

3. Code implementation

#include <iostream>
#include <string>
#include <vector>
#include <list>

using namespace std;


//Student class
//The type of element stored in the collection
class Student
{
public:
	string _name;			//full name
	string _stuNo;			//Student number
	string _college;		//college
public:
	Student(const string& name, const string& stuNo, const string& college)
		:_name(name)
		, _stuNo(stuNo)
		, _college(college)
	{}

	//Display student information
	void showInfo()
	{
		cout << "full name: " << _name << "\t Student number: " << _stuNo << "\t college: " << _college << endl;
	}
};

//Abstract iterator
class Iterator
{
public:
	//Is there an element in the next position
	virtual bool hasNext() = 0;
	//Returns the current element and moves to the next position
	virtual Student next() = 0;
};

//Computer iterator
class ComputerIterator : public Iterator
{
private:
	vector<Student> _info;		//The collection of data accessed by the iterator
	int _curPos;				//Subscript location currently accessed
public:
	ComputerIterator(const vector<Student>& info)
		:_info(info)
		, _curPos(0)
	{}

	//Is there an element in the next position
	virtual bool hasNext()
	{
		return _curPos < _info.size();
	}
	//Returns the current element and moves to the next position
	virtual Student next()
	{
		Student curStu = _info[_curPos++];
		return curStu;
	}
};



//Physical Education Institute iterator
//Because the internal container for storing data is list
//In order not to use the iterator provided by STL, the traversal order is from the head to the tail of the linked list
//The linked list header element is deleted after each access to the element
class SportIterator : public Iterator
{
private:
	list<Student> _info;		//The collection of data accessed by the iterator
public:
	//Is there an element in the next position
	virtual bool hasNext()
	{
		return !_info.empty();
	}
	//Returns the current element and moves to the next position
	virtual Student next()
	{
		Student front = _info.front();
		_info.pop_front();
		return front;
	}

	SportIterator(const list<Student>& info)
		:_info(info)
	{}
};

//Abstract aggregate class
class Aggregate
{
public:
	//Add student information
	virtual void addStudent(const Student& stu) = 0;
	//Delete student information
	virtual void deleteStudent(const Student& stu) = 0;
	//Create iterator
	virtual Iterator* createIterator() = 0;
};

//Computer College aggregation
class ComputerAggregate : public Aggregate
{
private:
	vector<Student> _info;		//Student information data manager

public:
	//Add student information
	virtual void addStudent(const Student& stu)
	{
		_info.emplace_back(stu);
	}

	//Delete student information
	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);
	}

	//Create iterator
	virtual Iterator* createIterator()
	{
		return new ComputerIterator(_info);
	}
};

//College of Physical Education
class SportAggregate : public Aggregate
{
private:
	list<Student> _info;		//A collection that stores student objects
public:
	//Add student information
	virtual void addStudent(const Student& stu)
	{
		_info.push_back(stu);
	}
	//Delete student information
	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);
	}
	//Create iterator
	virtual Iterator* createIterator()
	{
		return new SportIterator(_info);
	}
};

//Computer College Test
void test_College()
{
	Aggregate* computerCollege = new ComputerAggregate();
	computerCollege->addStudent(Student("Sauron", "11", "computer"));
	computerCollege->addStudent(Student("Red hair shanks", "12", "computer"));
	computerCollege->addStudent(Student("Monkey D Luffy", "13", "computer"));
	computerCollege->addStudent(Student("Nami", "14", "computer"));
	computerCollege->addStudent(Student("Yamaji", "15", "computer"));

	Iterator* it = computerCollege->createIterator();
	cout << "*************   school of computing   **************" << endl;
	while (it->hasNext())
	{
		it->next().showInfo();
	}
}

//Physical Education College Test
void test_Sport()
{
	Aggregate* sportCollege = new SportAggregate();
	sportCollege->addStudent(Student("White beard", "0", "Sports"));
	sportCollege->addStudent(Student("Raleigh", "1", "Sports"));
	sportCollege->addStudent(Student("Roger", "2", "Sports"));
	sportCollege->addStudent(Student("Ocado ", "3", "Sports"));
	sportCollege->addStudent(Student("Black beard", "4", "Sports"));
	sportCollege->addStudent(Student("BigMom", "5", "Sports"));

	Iterator* it = sportCollege->createIterator();
	cout << "*************   College of Physical Education   **************" << endl;
	while (it->hasNext())
	{
		it->next().showInfo();
	}
}



int main()
{
	test_College();

	cout << "\n\n\n\n" << endl;

	test_Sport();

	return 0;
}

Demonstration of operation results

4. Advantages and disadvantages

advantage:
In accordance with the opening and closing principle, if you need to traverse a new element set, you only need to add a new specific aggregation class and a specific iterator class;
Support different traversal methods on the same set;
Disadvantages:
Traversing the new collection requires adding a concrete aggregate class and a concrete iterator class, resulting in an increase in the number of classes

Keywords: C++ Design Pattern

Added by cedricm on Sun, 06 Mar 2022 06:10:04 +0200