迭代器模式
Iterator,提供一种方法顺序访问一个聚合对象中各个元素,而又不暴露该对象的内部表示。
迭代器模式就是分离了集合对象的遍历行为,抽象出一个迭代器类来负责,这样既可以做到不暴露集合的内部结构,又可让外部代码透明地访问集合内部的数据。
代码结构
结构图
代码(角色)
Iterator迭代器抽象类
/// <summary>
/// 迭代器抽象类
/// </summary>
abstract class Iterator
{
//用于定义得到开始对象,得到下一个对象,判断是否到结尾、当前对象等抽象方法,统一接口
public abstract object First();
public abstract object Next();
public abstract bool IsDone();
public abstract object CurrentItem();
}
Aggregate聚集抽象类
/// <summary>
///聚集抽象类
/// </summary>
abstract class Aggregate
{
public abstract Iterator CreateIterator(); //创建迭代器
}
ConcreteIterator具体迭代器类,继承Iterator。跟踪聚合中的当前对象,并能够计算出待遍历的后继对象。
/// <summary>
/// 具体迭代器类,继承Iterator
/// </summary>
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;
}
//判断当前是否遍历到结尾,到结尾返回true
public override bool IsDone()
{
return current >= aggregate.Count ? true : false;
}
public override object CurrentItem()
{
return aggregate[current]; //返回当前聚集对象
}
}
ConcreteAggregate具体聚集类,继承Aggregate。具体聚合实现创建相应迭代器的接口,该操作返回ConcreteIterator的一个适当的实例。
/// <summary>
/// 具体聚集类,继承Aggregate
/// </summary>
class ConcreteAggregate :Aggregate
{
//声明要给IList泛型变量,用于存放聚合对象,用ArryList同样可以实现
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); }
}
}
客户端代码
class Program
{
static void Main(string[] args)
{
ConcreteAggregate a = new ConcreteAggregate();
a[0] = "Dongle";
a[1] = "东子";
a[2] = "行李";
a[3] = "老外";
a[4] = "公交内部员工";
a[5] = "小偷";
Iterator i = new ConcreteIterator(a);
object item = i.First(); //从第一个乘客开始
while(!i.IsDone ())
{
Console.WriteLine("{0}请买车票!", i.CurrentItem()); //对面前的乘客告知请买票
i.Next(); //下一乘客
}
Console.ReadKey();
}
}
结果显示
使用环境
1.当需要一个聚集对象,而且不管这些对象是什么都需要遍历时;
2.为遍历不同的聚集结构提供统一的接口时;
3.需要对聚集有多种方法遍历时。
优点
1、它支持以不同的方式遍历一个聚合对象。
2、迭代器简化了聚合的接口
3、在同一个聚合上可以有多个遍历。
4、在迭代器模式中,增加新的聚合类和迭代器类都很方便,无须修改原有代码。
缺点
由于迭代器模式将存储数据和遍历数据的职责分离,增加新的聚合类需要对应增加新的迭代器类,类的个数成对增加,这在一定程度上增加了系统的复杂性。