这是个人学习编程模式的系列学习笔记第十五篇。
采用Qt Creator进行编写,但尽量采用C++基础语法。
迭代器模式(Iterator Pattern):提供一种方法顺序访问一个聚合对象中各个元素 , 而又不需暴露该对象的内部表示。
由于迭代器模式引用太过于广泛,大部分现代语言都将这个模式引入语言中直接支持(foreach in),甚至有人建议将这个模式从23种设计模式中去除。
场景描述
设计一个迭代器,通过迭代器可以对含多个数据的聚集类进行遍历。
设计思路
设计一个抽象迭代类,定义first、next、isDone、 current接口。派生具体的迭代类,实现具体的接口功能。
设计一个抽象的聚集类,定义生成迭代类的接口。派生具体的迭代类,并提供内容存储对象、对内容取值和计数的方法。
UML
代码
由于类之间相互引用,代码不能放在同一个文件中,否则编译不通过。
Iterator.h文件
#include <iostream>
using namespace std;
class Iterator
{
public:
virtual string first() = 0;
virtual string next() = 0;
virtual bool isDone() = 0;
virtual string current() = 0;
};
ConcreteIterator.h 文件
#include "iterator.h"
#include "concreteaggregate.h"
#include <iostream>
using namespace std;
class ConcreteIterator : public Iterator
{
public:
ConcreteIterator(ConcreteAggregate *aggregate);
string first();
string next();
bool isDone();
string current();
private:
int m_current = 0;
ConcreteAggregate *m_aggregate;
};
ConcreteIterator.cpp文件
#include "concreteiterator.h"
ConcreteIterator::ConcreteIterator(ConcreteAggregate *aggregate)
{
m_aggregate = aggregate;
}
string ConcreteIterator::first()
{
return (m_aggregate->count() <= 0) ? "" : (*m_aggregate)[0];
}
string ConcreteIterator::next()
{
m_current++;
return (m_current < m_aggregate->count()) ? (*m_aggregate)[m_current] : "";
}
bool ConcreteIterator::isDone()
{
return (m_current == m_aggregate->count()) ? true : false;
}
string ConcreteIterator::current()
{
return (m_current < m_aggregate->count() ) ? (*m_aggregate)[m_current] : "";
}
Aggregate.h文件
#include "iterator.h"
class Aggregate
{
public:
virtual Iterator &creatIterator() = 0;
};
ConcreteAggregate.h 文件
#include "iterator.h"
#include "aggregate.h"
#include <vector>
#include <iostream>
using namespace std;
class ConcreteAggregate : public Aggregate
{
public:
Iterator &creatIterator();
string &operator[](size_t i);
void append(const string str);
size_t count();
private:
vector<string> items;
};
ConcreteAggregate.cpp 文件
#include "concreteaggregate.h"
#include "concreteiterator.h"
Iterator &ConcreteAggregate::creatIterator()
{
Iterator *iter = new ConcreteIterator(this);
return *iter;
}
string &ConcreteAggregate::operator[](size_t i)
{
static string str = "Error index";
return (items.size() > i) ? items[i] : str;
}
void ConcreteAggregate::append(const string str)
{
items.push_back(str);
}
size_t ConcreteAggregate::count()
{
return items.size();
}
main.cpp文件
#include <iostream>
using namespace std;
#include "iterator.h"
#include "concreteiterator.h"
#include "aggregate.h"
#include "concreteaggregate.h"
int main()
{
ConcreteAggregate aggregate = ConcreteAggregate();
aggregate.append("a");
aggregate.append("b");
aggregate.append("c");
aggregate.append("d");
Iterator *iter = new ConcreteIterator(&aggregate);
string str;
str = iter->first();
while(!iter->isDone())
{
cout<<iter->current()<<"\n";
iter->next();
}
return 0;
}