迭代器模式 -- 大话设计模式
在今天,读书有时是件“麻烦”事。它需要你付出时间,付出精力,还要付出一份心境。--仅以《大话设计模式》来祭奠那逝去的……
迭代器模式:分离了集合对象的遍历行为,抽象出一个迭代器类来负责,这样既可以做到不暴漏集合的内部结构,又可让外部代码透明地访问集合内部的数据
1.售票员售票
公交车进站,乘客上车,售票员登场,遍历乘客,购买车票
首先定义迭代器抽象类和聚集抽象类
/// <summary> /// 迭代器抽象类 /// </summary> public abstract class IAmyEnumerator { /// <summary> /// 得到开始对象 /// </summary> public abstract object First(); /// <summary> /// 得到下一个对象 /// </summary> public abstract object Next(); /// <summary> /// 是否到结尾 /// </summary> public abstract bool IsDone(); /// <summary> /// 当前对象 /// </summary> public abstract object CurrentItem(); } /// <summary> /// 聚集抽象类 /// </summary> public abstract class IAmyEnumerable { /// <summary> /// 创建迭代器 /// </summary> public abstract IAmyEnumerator GetAmyEnumerator(); }
定义售票员(具体迭代器类)和公交车类(具体聚集类)
/// <summary> /// 售票员类(具体迭代器类) /// </summary> public class TicketSeller : IAmyEnumerator { private Bus aggregate; private int current = 0; public TicketSeller(Bus 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() { return current >= aggregate.Count; } public override object CurrentItem() { return aggregate[current]; } } /// <summary> /// 公交车类(具体聚集类) /// </summary> public class Bus : IAmyEnumerable { //存放集合对象 private IList<object> items = new List<object>(); public override IAmyEnumerator GetAmyEnumerator() { return new TicketSeller(this); } /// <summary> /// 返回集合对象总数 /// </summary> public int Count { get { return items.Count; } } /// <summary> /// 声明一个索引器 /// </summary> public object this[int index] { get { return items[index]; } set { items.Insert(index, value); } } }
开始场景模拟
static void Main(string[] args) { //公交车进站 Bus bus = new Bus(); //乘客上车 bus[0] = "大鸟"; bus[1] = "小菜"; bus[2] = "乘客A"; //售票员登场 TicketSeller seller = new TicketSeller(bus); //遍历乘客,购买车票 object item = seller.First(); while (!seller.IsDone()) { Console.WriteLine("{0}请买车票!", seller.CurrentItem()); seller.Next(); } }