设计模式(4)--对象行为(4)--迭代器

2023-12-25 12:52:00
1. 意图

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

2. 四种角色

? ? 抽象集合(Aggregate)、具体集合(Concrete Aggregate)、抽象迭代器(Iterator)、具体迭代器(Concrete Iterator)

3. 优点

? ? 3.1 支持以不同的方式遍历一个聚合

? ? 3.2 简化了聚合的接口

? ? 3.3 在同一个聚合上可以有多个遍历

4. 缺点

? ? N/A

5. 相关模式

? ? 5.1 迭代器常被应用到Composite这样的递归结构上。

? ? 5.2 多态迭代器靠工厂方法来实例化适当的迭代器子类。

? ? 5.3 迭代器内部存储一个memento,用来捕获一个迭代的状态。

6. 代码示意(C++)
#pragma once
#include <vector>
#include <string>
#include <iostream>
using namespace std;

class Employee
{
	string m_name;
public:
	Employee(const string& name) :m_name(name) {

	}
	void Print() const {
		cout << m_name << endl;
	}
};

template <class T> class Iterator;
template <class T> class ForwardIterator;

template <class T>
class Aggregate
{
	friend class ForwardIterator<T>;
public:
	virtual void Add(T data) = 0;
	virtual Iterator<T>* CreateIterator() const = 0;
private:
	virtual int Size() const = 0;
	virtual const T* Get(long pos) const = 0;
};

template <class T>
class ConcreteAggregate : public Aggregate<T>
{
	vector<T> m_vector;
	Iterator<T>* m_pIt;
public:
	ConcreteAggregate() :m_pIt(0) {
	}
	~ConcreteAggregate() {
		delete m_pIt;
	}	
	virtual void Add(T data) {
		m_vector.emplace_back(data);
	}
	//方法一:用户需负责删除
	virtual Iterator<T>* CreateIterator() const {
		return new ForwardIterator<T>(this);
	}
	//方法二:析构函数负责删除
	virtual Iterator<T>& GetIterator() {
		//先删除老的
		delete m_pIt;
		m_pIt = new ForwardIterator<T>(this);
		return *m_pIt;
	}
private:
	virtual int Size() const { return m_vector.size(); }
	virtual const T* Get(long pos) const { return &(m_vector[pos]); }
};

template <class T>
class Iterator
{
public:
	virtual void First() = 0;
	virtual void Next() = 0;
	virtual bool IsDone() const = 0;
	virtual const T* CurrentItem() const = 0;
protected:
	Iterator() {}
};

template <class T>
class ForwardIterator : public Iterator<T> {
public:
	ForwardIterator(const Aggregate<T>* pData);
	virtual void First();
	virtual void Next();
	virtual bool IsDone() const;
	virtual const T* CurrentItem() const;
private:
	const Aggregate<T>* m_pData;
	long m_current;

};
template<class T>
ForwardIterator<T>::ForwardIterator(const Aggregate<T>* pData) :m_pData(pData), m_current(0)
{
}

template<class T>
void ForwardIterator<T>::First() {
	m_current = 0;
}

template<class T>
void ForwardIterator<T>::Next() {
	++m_current;
}

template<class T>
bool ForwardIterator<T>::IsDone() const {
	return m_current >= m_pData->Size();
}

template<class T>
const T* ForwardIterator<T>::CurrentItem() const {
	if (IsDone()) {
		return 0;
	}
	return m_pData->Get(m_current);
}
#include "Iterator.h"
int main() {
	//方法一
	Aggregate<Employee>* pAggregate = new ConcreteAggregate<Employee>();
	pAggregate->Add(Employee("张三"));
	pAggregate->Add(Employee("李四"));

	Iterator<Employee>* pIt = pAggregate->CreateIterator();
	for (pIt->First(); !pIt->IsDone(); pIt->Next()) {
		pIt->CurrentItem()->Print();
	}
	cout << endl;
	delete pIt;
	delete pAggregate;

	//方法二
	ConcreteAggregate<Employee> aggregate;
	aggregate.Add(Employee("王五"));
	aggregate.Add(Employee("赵六"));

	Iterator<Employee> &it = aggregate.GetIterator();
	for (it.First(); !it.IsDone(); it.Next()) {
		it.CurrentItem()->Print();
	}

	return 0;
}

运行结果:

6.1 可以很容易实现Iterator的子类以支持不同的遍历方式(3.1)

6.2 使用方法一,可以得到多个迭代器,但用户需要负责删除迭代器指针(3.3);

? ? ? ?而方法二则不需要用户删除指针(也可用代理类得到相同效果)?。

文章来源:https://blog.csdn.net/myepicure/article/details/134909779
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。