迭代器模式定义:提供一种方法顺序的访问一组聚合元素,而又不暴露该对象的内部结构。
说明:首先说明,使用迭代器的对象必须是一组聚合对象,比如公交车就是一组聚合对象,车内的人互相之间可能有关系,可能没关系,他们组合起来组成了这个聚合对象。并且,这个顺序可以是任何顺序,比如从大到小,或者从小到大,也就是说迭代器迭代一个对象时,下一个对象已经确定了,这个而对象是唯一的。最后就是内部结构,其实我们只是从外部可以得到这个对象的值,但是聚合对象内部的构造,我们是不清楚的。
迭代器类图:
代码实现:
class Program
{
static void Main(string[] args)
{
ConcreteAggregate a = new ConcreteAggregate(); //公交车,即聚集对象
a[0] = "大鸟"; //新上来的乘客,即对象组
a[1] = "小菜";
a[2] = "行李";
a[3] = "老外";
a[4] = "内部员工";
a[5] = "小偷";
a[6] = "体制内人员";
Iterator i = new ConcreteIterator(a); //售票员出场,先看好那些人上车,即申明迭代器对象
object item = i.First(); //从第一个人开始
while (!i.IsDone()) //判断是否买票
{
Console.WriteLine("{0}请买车票", i.CurrentItem ()); //让当前对象买票
i.Next(); //下一个乘客
}
Console.Read();
}
}
abstract class Iterator //迭代器抽象类、接口
{
public abstract object First(); //定义开始对象
public abstract object Next(); //下一个对象
public abstract bool IsDone(); //判断是否到结尾
public abstract object CurrentItem(); //当前对象
}
class ConcreteIterator : Iterator
{
private ConcreteAggregate aggregate; //定义了一个具体聚集对象
private int current = 0;
public ConcreteIterator(ConcreteAggregate aggregate) //初始化时将具体的聚集对象传入
{
this.aggregate = aggregate;
}
public override object First() ///得到聚集到额第一个对象
{
return aggregate[0];
}
public override object Next() //得到下一个对象
{
object ret = null;
current++;
if (current < aggregate.Count)
{
ret = aggregate[current ];
}
return ret;
}
public override bool IsDone() //判断是否便利到结尾,结尾时返回TRUE
{
return current >= aggregate.Count ? true : false;
}
public override object CurrentItem() //返回当前的聚集对象
{
return aggregate[current ];
}
}
abstract class Aggregate //聚集抽象类
{
public abstract Iterator CreateIterator(); //创建迭代器
}
class ConcreteAggregate : Aggregate
{
private IList <object > items = new List<object >(); //生命一个IList泛型变量,用于存放聚合对象,用ArrayList也可以实现
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 ); }
}
}
因为迭代器在编程中泰常见了,所以高级语言将迭代器进行了高度的抽象,比如说数组、ArryList、集合、哈希表、字典都进行了封装,所以我们平时并不会注意到这个模式。
接下来看看.net内置的迭代器。
class Program
{
static void Main(string[] args)
{
IList<string > a = new List<string > ();
a.Add("大鸟");
a.Add("小菜");
a.Add("行李");
a.Add("老外");
a.Add("体制内人员");
a.Add("员工");
a.Add("小偷");
foreach (string item in a)
{
Console.WriteLine("{0}请买车票", item);
}
Console.Read();
}
}
public interface IEumerator
{
object Current //获取集合中的当前元素
{
get;
}
bool MoveNext(); //将枚举进行到集合中的下一个元素。用bool值标记。
void Reset(); //恢复初始化只想的位置,该位置位于集合中第一个元素之前
}
public interface IEnumerable //返回一个循环访问集合的枚举数
{
IEumerator GetEnumerator();
}
如果我们想在自定义的数据结构中添加迭代器,改如何实现呢?
我们只需要继承 并实现接口IEnumerable 即可。