设计模式(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
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!