迭代器模式
概述
提供一种方法顺序访问一个集合对象中各个元素,而又不暴露该对象的内部表示
一个完整的迭代器模式一般会涉及容器和容器迭代器两部分内容。
很多编程语言都将迭代器作为一个基础的类库,直接提供出来了。在平时开发中,特别是业务开发,我们直接使用即可,很少会自己去实现一个迭代器。
结构图
代码实现
聚集类
/// <summary> /// 聚集抽象类 /// </summary> public abstract class Aggregate { public abstract Iterator CreateIterator(); }
/// <summary> /// 具体聚集类 /// </summary> public class ConcreteAggregate : Aggregate { 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); } } }
迭代器类
/// <summary> /// 迭代器抽象类 /// </summary> public abstract class Iterator { public abstract object First(); public abstract object Next(); public abstract bool IsDone(); public abstract object CurrentItem(); }
/// <summary> /// 具体迭代器类(从前往后遍历) /// </summary> public 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 object CurrentItem() { return aggregate[current]; } public override bool IsDone() { return current >= aggregate.Count ? true : false; } }
/// <summary> /// 具体迭代器类(从后往前遍历) /// </summary> public class ConcreteIteratorDesc : Iterator { private ConcreteAggregate aggregate; private int current = 0; public ConcreteIteratorDesc(ConcreteAggregate aggregate) { this.aggregate = aggregate; current = aggregate.Count - 1; } public override object First() { return aggregate[aggregate.Count - 1]; } public override object Next() { object ret = null; current--; if (current >= 0) { ret = aggregate[current]; } return ret; } public override object CurrentItem() { return aggregate[current]; } public override bool IsDone() { return current < 0 ? true : false; } }
客户端
class Program { static void Main(string[] args) { ConcreteAggregate a = new ConcreteAggregate(); a[0] = "数据a"; a[1] = "数据b"; a[2] = "数据c"; a[3] = "数据d"; a[4] = "数据e"; a[5] = "数据f"; Iterator i = new ConcreteIterator(a); object item = i.First(); while (!i.IsDone()) { Console.WriteLine(i.CurrentItem()); i.Next(); } Iterator id = new ConcreteIteratorDesc(a); object itemd = i.First(); while (!id.IsDone()) { Console.WriteLine(id.CurrentItem()); id.Next(); } Console.Read(); } }
运行结果
优势
访问一个聚合对象的内容而无须暴露它的内部表示。
遍历任务交由迭代器完成,这简化了聚合类。
它支持以不同方式遍历一个聚合,甚至可以自定义迭代器的子类以支持新的遍历。
在迭代器模式中,增加新的聚合类和迭代器类都很方便,无须修改原有代码。
使用场景
在日常开发中,我们几乎不会自己写迭代器。除非需要定制一个自己实现的数据结构对应的迭代器,否则,开源框架提供的 API 完全够用。
缺陷
由于迭代器模式将存储数据和遍历数据的职责分离,增加新的聚合类需要对应增加新的迭代器类,类的个数成对增加,这在一定程度上增加了系统的复杂性。