迭代器模式应该包含两个基本元素,一个集合,一个迭代器。迭代器用来遍历这个集合来做出相应的操作。在此模式之前,需要用到遍历对象的用此模式比较多,现在这种模式逐步被封装到语言中了,比如Foreach in 函数,其实就是一个迭代器。
举一个简单的场景来理解这个模式,比如我们常常上班要坐的公交车,集合就好比车里的乘客,迭代器就好比售票员。售票员不关心乘客是什么身份(集合元素的类型),他只关心你有没有买票,所以他经常做的事情就是从头(他认为的第一个人开始遍历)到结束都要询问一遍,对于售票员要做1.从谁开始,2.当前的乘客,3.下一个我要问的是谁,4.是否都问完了。
所以迭代器模式基本就是一个不管遍历方式,不管遍历的元素类型的遍历模式。基于此我们可以把他们基本结构写出来了。
抽象的迭代器
abstract class Iterator
{
public abstract object First();
public abstract object Current();
public abstract object Next();
public abstract bool IsDone();
}
抽象的集合
abstract class Aggregate
{
}
集合好比公交车,所以我们得让售票员上车(初始化迭代器),所以抽象的集合应该变为:
abstract class Aggregate
{
//在集合中建立(返回迭代器类型的)创建迭代器的函数
public abstract Iterator Createiterator();
}
他们基本抽象类都已经完成了,下面就具体实现一下吧!
具体的集合ConcreteAggregate(公交车哦)
class ConcreteAggregate:Aggregate
{
//定义成员变量(定义乘客列表集合),乘客的类型为object,因为
//不管你是什么人,只要交钱就能上车,哈哈
private IList<object> items = new List<object>();
public override Iterator Createiterator()
{
//告诉售票员(迭代器)我是那辆车(集合)
return new ConcreteIterator(this);
}
//定义一个总数的属性(只有属性采油属性访问器)
public int Count
{
get { return items.Count; }
}
public object this[int index]
{
get { return items[index]; }
set { items.Insert(index, value); }
}
}
具体的迭代器ConcreteIterator
class ConcreteIterator:Iterator
{
//定义一个集合(先告诉自己要上一辆公交车:) )
private ConcreteAggregate ConAggregate;
private int currentItem=0;
//构造函数,在此类创建时用于初始化数据(找到车就上车咯!)
public ConcreteIterator(ConcreteAggregate conaggr)
{
this.ConAggregate = conaggr;
}
public override object First()
{
return ConAggregate[0];
}
public override object Current()
{
return ConAggregate[currentItem];
}
public override object Next()
{
object ret = null;
currentItem++;
if (currentItem <= ConAggregate.Count)
{
ret = ConAggregate[currentItem];
}
return ret;
}
public override bool IsDone()
{
return currentItem >= ConAggregate.Count ? true : false;
}
}
注:上面这段代码初看没问题,但是我运行之后发现有数据溢出,仔细看过之后是currentItem这个索引到本Demo最大值为4时,在ConcreteAggregate中items【index】也会为4,到此就会数据溢出,出现异常,讲其修改之后的代码:
public override object Next()
{
object ret = null;
currentItem++;
if (currentItem <= ConAggregate.Count)
{
ret = ConAggregate[currentItem-1];
}
return ret;
}
下面我们就以售票员为例写一下客户端代码:
static void Main(string[] args)
{
//创建一个集合的实例,并初始化。
ConcreteAggregate Bus = new ConcreteAggregate();
//成员开始上车咯!
Bus[0] = "小明";
Bus[1] = "小红";
Bus[2] = "小菜";
Bus[3] = "小李";
//售票员上场咯!
Iterator busboy = new ConcreteIterator(Bus);
//开始检票了,从第一个人开始查看
object item = busboy.First();
while (!busboy.IsDone())
{
Console.WriteLine("{0}请买票!",busboy.Current());
busboy.Next();
}
Console.Read();
}