定义
提供一种方法顺序访问一个聚合对象中各个元素,而又不暴露该对象的内部表示。
聚合类
可以存储多个成员对象(聚会对象)
聚合对象
拥有两个职责:一是存储数据,二是遍历数据
由迭代器来提供遍历聚合对象内部数据的行为
举例
常见的编程语言中的迭代器,for in语法,用遥控器上下按钮切换电视频道
结构
实现
//迭代器抽象类
abstract class Iterator
{
public abstract object First();
public abstract object Next();
public abstract bool IsDone();
public abstract object CurrentItem();
}
//聚集抽象类
abstract class Aggregate
{
public abstract Iterator CreateIterator();
}
//具体迭代器类
class ConcreteIterator : Iterator
{
//定义了一个具体聚集对象
private ConcreteAggreate aggregate;
private int current = 0;
//初始化时将具体的聚集对象传入
public ConcreteIterator(ConcreteAggreate aggregate)
{
this.aggregate = aggregate;
}
//返回当前聚焦的对象
public override object CurrentItem()
{
return aggregate[current];
}
//得到聚集的第一个对象
public override object First()
{
return aggregate[0];
}
public override bool IsDone()
{
return current >= aggregate.Count ? true : false;
}
//得到聚集的下一个对象
public override object Next()
{
object ret = null;
current++;
if(current < aggregate.Count)
{
ret = aggregate[current];
}
return ret;
}
}
//具体聚集类
class ConcreteAggreate: Aggregate
{
//声明一个IList泛型变量,用于存放聚合对象,用ArrayList同样可以实现
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)
{
//聚集对象
ConcreteAggreate a = new ConcreteAggreate();
//对象数组
a[0] = "小李";
a[1] = "小兰";
a[2] = "小岩";
a[3] = "小环";
a[4] = "小茜";
//声明迭代器对象
Iterator i = new ConcreteIterator(a);
object item = i.First();
//遍历
while (!i.IsDone())
{
Console.WriteLine("顺序:{0}", i.CurrentItem());
i.Next();
}
}
}
优点
- (1)迭代器模式支持以不同的方式遍历一个聚合对象,在同一个聚合对象上可以定义多种遍历方式。在迭代器模式中,只需要用一个不同的迭代器来替换原有迭代器即可改变遍历算法,用户也可以自己定义迭代器的子类以支持新的遍历方式。
- (2)迭代器模式简化了聚合类。由于引入了迭代器,在原有的聚合对象中不需要再自行提供数据遍历等方法,这样可以简化聚合类的设计。
- (3)在迭代器模式中,由于引入了抽象层,增加新的聚合类和迭代器类都很方便,无须修改原有代码,符合开闭原则。
缺点
- (1)由于迭代器模式将存储数据和遍历数据的职责分离,在增加新的聚合类时需要对应地增加新的迭代器类,类的个数成对增加,这在一定程度上增加了系统的复杂性。
- (2)抽象迭代器的设计难度较大,需要充分考虑系统将来的扩展。在自定义迭代器时,创建一个考虑全面的抽象迭代器并不是一件很容易的事情。
适用环境
- (1)访问一个聚合对象的内容而无须暴露它的内部表示。将聚合对象的访问与内部数据的存储分离,使得访问聚合对象时无须了解其内部实现细节。
- (2)需要为一个聚合对象提供多种遍历方式。
- (3)为遍历不同的聚合结构提供一个统一的接口,在该接口的实现类中为不同的聚合结构提供不同的遍历方式,而客户端可以一致性地操作该接口。