第二十章想走可以先买票--迭代器模式
20.1 乘车买票,不管你是谁!
不管你是小偷还是公交公司的人,只要上了这俩车,都要买票。售票员其实做了一件重要的事,就是把车厢里的所有人都遍历了一遍,不放过一个不买票的乘客,这也是一个设计模式的体现。这个设计者模式的名字就叫作迭代器模式。
20.2 迭代器模式
提供一种方法顺序访问一个聚合对象中各个元素,而不是暴露该对象的内部表示。就像售票员不管你上来的是人还是行李,不管是中国人还是外国人,不管是不是内部员工,甚至是马上要被抓走的小偷,只要是来乘车的乘客,就必须要买票。
当你需要访问一个聚集对象,而且 不管这些对象是什么都需要遍历的时候,你就应该考虑用迭代器模式。为遍历不同的聚集结构提供如开始,下一个,是否结束,当前哪一项等统一的接口。
20.3 迭代器实现
#pragma once
#include <string>
class MyObject
{
public:
MyObject(std::string str)
{
strValue = str;
}
std::string strValue;
};
Aggregate聚集抽象类
#pragma once
#include <vector>
#include "MyObject.h"
class MyIterator;
class Aggregate
{
public:
virtual MyIterator* CreateIterator(void) = 0;
};
class ConcreteAggregate :public Aggregate
{
public:
MyIterator* CreateIterator(void);
ConcreteAggregate(void);
~ConcreteAggregate(void);
int GetCount(void);
MyObject* operator[](int index);
void SetThis(MyObject* p);
private:
std::vector<MyObject*> m_list;
};
include "Aggregate.h"
#include "MyIterator.h"
MyIterator* ConcreteAggregate::CreateIterator(void)
{
return new ConcreteIterator(this);
};
ConcreteAggregate::ConcreteAggregate(void)
{
m_list.reserve(10);
};
ConcreteAggregate::~ConcreteAggregate(void)
{
m_list.clear();
};
int ConcreteAggregate::GetCount(void)
{
return m_list.size();
}
MyObject* ConcreteAggregate::operator[](int index)
{
return m_list[index];
};
void ConcreteAggregate::SetThis(MyObject* p)
{
m_list.push_back(p);
};
Iterator迭代器抽象类
具体迭代器类,继承Iterator
ConcreteAggregate具体聚集类,继承Aggregate
#pragma once
#include "Aggregate.h"
#include "MyObject.h"
class ConcreteAggregate;
class MyIterator
{
public:
virtual MyObject* First(void) = 0;
virtual MyObject* Next(void) = 0;
virtual bool IsDone(void) = 0;
virtual MyObject* CurrentItem(void) = 0;
};
class ConcreteIterator :public MyIterator
{
public:
ConcreteIterator(ConcreteAggregate* p)
{
currentPos = 0;
m_pAggregate = p;
};
MyObject* First(void)
{
return (*m_pAggregate)[0];
};
MyObject* Next(void)
{
MyObject* ret = NULL;
++currentPos;
if (currentPos < m_pAggregate->GetCount())
{
ret = (*m_pAggregate)[currentPos];
}
return ret;
};
bool IsDone(void)
{
return currentPos < m_pAggregate->GetCount() ? false :true ;
};
MyObject* CurrentItem(void)
{
return (*m_pAggregate)[currentPos];
};
private:
ConcreteAggregate* m_pAggregate;
int currentPos;
};
//媡偺曽朄
class ConcreteIteratorDesc :public MyIterator
{
public:
ConcreteIteratorDesc(ConcreteAggregate* p)
{
m_pAggregate = p;
currentPos = p->GetCount() - 1;
};
MyObject* First(void)
{
return (*m_pAggregate)[m_pAggregate->GetCount() - 1];
};
MyObject* Next(void)
{
MyObject* ret = NULL;
--currentPos;
if ( currentPos > 0 )
{
ret = (*m_pAggregate)[currentPos];
}
return ret;
};
bool IsDone(void)
{
return currentPos >= 0 ? false :true ;
};
MyObject* CurrentItem(void)
{
return (*m_pAggregate)[currentPos];
};
private:
ConcreteAggregate* m_pAggregate;
int currentPos;
};
客户端代码
// DesignPattern20.3.cpp : 僐儞僜乕儖 傾僾儕働乕僔儑儞偺僄儞僩儕 億僀儞僩傪掕媊偟傑偡丅
//
#include "stdafx.h"
#include "MyIterator.h"
#include "Aggregate.h"
#include <iostream>
int _tmain(int argc, _TCHAR* argv[])
{
MyObject valueList1("彫嵷");
MyObject valueList2("戝捁");
MyObject valueList3("壸暔");
MyObject valueList4("奜崙幰");
MyObject valueList5("撪晹幮堳");
MyObject valueList6("揇朹");
ConcreteAggregate* agg = new ConcreteAggregate();
agg->SetThis(&valueList1);
agg->SetThis(&valueList2);
agg->SetThis(&valueList3);
agg->SetThis(&valueList4);
agg->SetThis(&valueList5);
agg->SetThis(&valueList6);
MyIterator* iter = new ConcreteIterator(agg);
while (!iter->IsDone())
{
std::cout << iter->CurrentItem()->strValue << std::endl;
iter->Next();
}
MyIterator* iterDesc = new ConcreteIteratorDesc(agg);
while (!iterDesc->IsDone())
{
std::cout << iterDesc->CurrentItem()->strValue << std::endl;
iterDesc->Next();
}
delete agg;
delete iter;
delete iterDesc;
return 0;
}
20.4 .NET的迭代器实现
IEumerator支持对非泛型集合的简单迭代接口。迭代器模式就是分离了集合对象的遍历行为,抽象出一个迭代器类来负责,这样既可以做到不暴露集合的内部结构,又可让外部代码透明地访问集合内部的数据。