设计模式【22】——迭代器模式(Iterator 模式)


前言

Iterator 模式十分常见。当我们开发cpp文件时,经常会使用STL里面的容器,如vector、map、set等,对容器进行遍历的时候就用到了里面提供的Iterator来遍历数据结构
Iterator模式也正是用来解决对一个聚合对象的遍历问题。其将对聚合的遍历封装到一个类中进行,这样就避免了暴露这个聚合对象的内部表示的可能。


一、迭代器模式(Iterator 模式)

Iterator模式中定义的对外接口可以视客户成员的便捷定义,但是基本的接口在图中的Iterator中已经给出了(参考 STL 的 Iterator 就知道了)。UML图如下:
Iterator 模式示意图


二、具体源码

1.Aggregate.h

代码如下(示例):

#ifndef _AGGREGATE_H_ 
#define _AGGREGATE_H_ 

#include <iostream>
#include <vector>
typedef int Object;

class Iterator;
class Interator;

class Aggregate
{
public:

  virtual ~Aggregate();
  virtual Iterator* CreateIterator() = 0;
  virtual Object GetItem(int idx) = 0;
  virtual int GetSize() = 0;

protected:
  Aggregate();
private:
};

class ConcreteAggregate :public Aggregate
{
public:

  ConcreteAggregate(int size);
  ~ConcreteAggregate();
  Iterator* CreateIterator();
  Object GetItem(int idx);
  int GetSize();

protected:
private:
  std::vector<Object> _objs;
};
#endif //_AGGREGATE_H_

2.Aggregate.cpp

代码如下(示例):

#include "Aggregate.h" 
#include "Iterator.h"

Aggregate::Aggregate()
{
}

Aggregate::~Aggregate()
{
}

ConcreteAggregate::ConcreteAggregate(int size)
{
  this->_objs.resize(size, 0);
  for (int i = 0; i < size; i++)
  {
    this->_objs[i] =i * i;
  }
}

ConcreteAggregate::~ConcreteAggregate()
{
}

Iterator* ConcreteAggregate::CreateIterator()
{
  return new ConcreteIterator(this);
}

Object ConcreteAggregate::GetItem(int idx)
{
  if (idx < this->GetSize())
    return _objs[idx];
  else
  return -1;
}

int ConcreteAggregate::GetSize()
{
  return this->_objs.size();
}

3.Iterator.h

#pragma once

#ifndef _ITERATOR_H_ 
#define _ITERATOR_H_ 

class Aggregate;
typedef int Object;

class Iterator
{
public:

  virtual ~Iterator();
  virtual void First() = 0;
  virtual void Next() = 0;
  virtual bool IsDone() = 0;
  virtual Object CurrentItem() = 0;

protected:
  Iterator();
private:
};

class ConcreteIterator :public Iterator
{
public:

  ConcreteIterator(Aggregate* ag, int idx = 0);
  ~ConcreteIterator();
  void First();
  void Next();
  bool IsDone();
  Object CurrentItem();

protected:
private:
  Aggregate* _ag;
  int _idx;
};
#endif //_ITERATOR_H_

4.Iterator.cpp

#include "Iterator.h"
#include "Aggregate.h" 

Iterator::Iterator()
{
}

Iterator::~Iterator()
{
}

ConcreteIterator::ConcreteIterator(Aggregate* ag, int idx)
{
  this->_ag = ag;
  this->_idx = idx;
}
ConcreteIterator::~ConcreteIterator()
{
}

Object ConcreteIterator::CurrentItem()
{
  return _ag->GetItem(_idx);
}

void ConcreteIterator::First()
{
  _idx = 0;
}

void ConcreteIterator::Next()
{
  if (_idx < _ag->GetSize())
    _idx++;
}

bool ConcreteIterator::IsDone()
{
  return (_idx == _ag->GetSize());
}

5.main.cpp

#include "Iterator.h"
#include "Aggregate.h" 

int main(int argc, char* argv[])
{
  const int size = 10;
  Aggregate* ag = new ConcreteAggregate(size);
  //默认从头开始遍历
  Iterator* it1 = new ConcreteIterator(ag);

  for (; !(it1->IsDone()); it1->Next())
  {
    std::cout << it1->CurrentItem() << std::endl;
  }

  std::cout << std::endl;
  std::cout << "No start from first!!!" << std::endl;
  Iterator* it2 = new ConcreteIterator(ag,5);

  for (; !(it2->IsDone()); it2->Next())
  {
    std::cout << it2->CurrentItem() << std::endl;
  }

  return 0;
}

三、运行结果

Iterator 模式的运行结果如下:
Iterator 模式运行结果

总结

Iterator 模式中迭代器简化了聚合类,支持以不同的方式遍历一个聚合对象。 而且增加新的聚合类和迭代器类都很方便,无须修改原有代码。但是由于存储数据和遍历数据的职责分离,增加新的聚合类需要对应增加新的迭代器类,增加了系统的复杂度。


本文参考《设计模式精解-GoF 23 种设计模式解析附 C++实现源码》,对内容进行整理,方便大家学习。如想学习详细内容,请参考此书。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

希望早日退休的程序猿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值