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

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 
#include 
#include 
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 Iterator;
template  class ForwardIterator;

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

template 
class ConcreteAggregate : public Aggregate
{
	vector m_vector;
	Iterator* m_pIt;
public:
	ConcreteAggregate() :m_pIt(0) {
	}
	~ConcreteAggregate() {
		delete m_pIt;
	}	
	virtual void Add(T data) {
		m_vector.emplace_back(data);
	}
	//方法一:用户需负责删除
	virtual Iterator* CreateIterator() const {
		return new ForwardIterator(this);
	}
	//方法二:析构函数负责删除
	virtual Iterator& GetIterator() {
		//先删除老的
		delete m_pIt;
		m_pIt = new ForwardIterator(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 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 ForwardIterator : public Iterator {
public:
	ForwardIterator(const Aggregate* pData);
	virtual void First();
	virtual void Next();
	virtual bool IsDone() const;
	virtual const T* CurrentItem() const;
private:
	const Aggregate* m_pData;
	long m_current;

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

template
void ForwardIterator::First() {
	m_current = 0;
}

template
void ForwardIterator::Next() {
	++m_current;
}

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

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

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

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

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

	return 0;
}

运行结果:

设计模式(4)--对象行为(4)--迭代器_第1张图片

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

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

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

你可能感兴趣的:(设计模式,设计模式)