迭代器模式是一种行为型模式
优点:
- 它支持以不同的方式遍历一个聚合对象,而无需暴露它的内部表示。
- 迭代器简化了聚合类。
- 在迭代器模式中,由于引入了抽象层,增加新的聚合类和迭代器类都很方便,无需修改原有代码。
缺点:
- 由于多了一个抽象层,会增加系统的复杂性。
- 对于简单的遍历(如数组),使用迭代器方式遍历较为繁琐。
- 总之,迭代器模式在需要对聚合对象进行遍历时非常有用,它可以让用户通过特定的接口访问容器中的数据,而无需了解容器内部实现细节。
满足的设计原理:
- “单一职责原则”要求一个类应该只有一个引起它变化的原因。在迭代器模式中,遍历操作被分离到了迭代器类中,使得聚合类和迭代器类各自只负责一件事,符合单一职责原则。
- “迪米特法则”要求一个对象应当对其他对象有尽可能少的了解。在迭代器模式中,客户端只需要知道迭代器的接口,而无需了解聚合对象的内部实现,符合迪米特法则。
常用实例:
迭代器模式常用于遍历各种容器,如链表、数组、树等。例如,在STL(C++标准模板库)中,就广泛使用了迭代器模式。STL中的容器(如vector、list、set等)都提供了迭代器,可以使用迭代器来遍历容器中的元素。
类图:
常规代码:
#include "iostream"
#include "string"
#include <vector>
using namespace std;
class Aggregate
{
public:
virtual ~Aggregate(){};
virtual class Iterator*CreateIterator()=0;
};
class Iterator
{
public:
virtual ~Iterator(){}
virtual void First()=0;
virtual void Next()=0;
virtual bool IsDone()=0;
virtual int CurrentItem()=0;
};
class ConcretaAggregate:public Aggregate {
public:
ConcretaAggregate(initializer_list<int> values):values_(values){}
Iterator*CreateIterator();
int Count()const
{
return values_.size();
}
int Get(int index)const
{
return values_[index];
}
private:
vector<int> values_;
};
class ConcreteIterator :public Iterator {
public:
ConcreteIterator(const ConcretaAggregate*aggregate):aggregate_(aggregate),current_(0){}
void First()
{
current_=0;
}
void Next()
{
++current_;
}
bool IsDone()
{
return current_>=aggregate_->Count();
}
int CurrentItem()
{
return aggregate_->Get(current_);
}
private:
const ConcretaAggregate*aggregate_;
int current_;
};
Iterator* ConcretaAggregate::CreateIterator()
{
return new ConcreteIterator(this);
}
int main()
{
ConcretaAggregate aggregate{1,2,3,4,5};
Iterator*it=aggregate.CreateIterator();
for (it->First();!it->IsDone();it->Next())
{
cout<<it->CurrentItem()<<endl;
}
vector<int> nu{1,2,3};
for (vector<int>::iterator it=nu.begin();it!=nu.end();it++)
{
}
return 0;
}
STL C++ 标准容器类中类代码:
template<typename T>
class AA {
public:
class iterator {
public:
iterator(T* ptr) : _ptr(ptr) {}
iterator operator++() { ++_ptr; return *this; }
bool operator!=(const iterator& other) const { return _ptr != other._ptr; }
T operator*() const { return *_ptr; }
private:
T* _ptr;
};
AA(T* num, int size) : _num(num), _size(size) {}
iterator begin() { return iterator(_num); }
iterator end() { return iterator(_num + _size); }
private:
T* _num;
int _size;
};
int main() {
int num[] = { 1, 2, 3, 4, 5 };
AA<int> aa(num, sizeof(num) / sizeof(int));
for (AA<int>::iterator it = aa.begin(); it != aa.end(); ++it) {
std::cout << *it << std::endl;
}
return 0;
}