<1>在面向对象的软件设计中,我们经常会遇到一类集合对象,这类集合对象的内部结构可能有着各种各样的实现,但是归结起来,无非有两点是需要我们去关心的:一是集合内部的数据存储结构,二是遍历集合内部的数据。面向对象设计原则中有一条是类的单一职责原则,所以我们要尽可能的去分解这些职责,用不同的类去承担不同的职责。
<2>Iterator模式就是分离了集合对象的遍历行为,抽象出一个迭代器类来负责,这样既可以做到不暴露集合的内部结构,又可让外部代码透明的访问集合内部的数据。
提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露该对象的内部表示。
——《设计模式》GoF
<1>在公交车上,售票员不管上来的是什么人,总会要求每个人都来买票。
<2>不管乘客是什么,售票员的做法都是相同的:
从第一个开始
当前是谁
下一个
是否结束
namespace Test
{
///
/// 迭代器,用来执行迭代操作
///
public abstract class Iterator
{
public abstract object First(); //第一个
public abstract object CurrentItem(); //当前这一个
public abstract object Next(); //下一个
public abstract bool IsDone(); //结束了没有?
}
///
/// 聚合类,代表一个可迭代的集合
///
public abstract class Aggregate
{
public abstract Iterator CreateIterator(); //返回一个迭代器
}
///
/// ConcreteAggregate 具体的聚合类
///
public class 车上的乘客 : Aggregate
{
private System.Collections.ArrayList al = new System.Collections.ArrayList();
public override Iterator CreateIterator()
{
return new ConcreteIterator(this);
}
public void 上车(string 乘客姓名)
{
this.al.Add(乘客姓名);
}
public string this[int index]
{
get
{
return this.al[index].ToString();
}
}
public int 数量
{
get
{
return this.al.Count;
}
}
}
///
/// ConcreteIterator 具体的迭代器
///
public class ConcreteIterator : Iterator
{
private 车上的乘客 _乘客们 = null;
private int 当前第几个 = 0;
public ConcreteIterator(车上的乘客 乘客)
{
this._乘客们 = 乘客;
}
public override object First()
{
if (this._乘客们.数量 > 0)
{
this.当前第几个 = 0;
return this._乘客们[0];
}
else
{
return null;
}
}
public override object CurrentItem()
{
return this._乘客们[当前第几个];
}
public override object Next()
{
this.当前第几个++;
if (this.当前第几个 < this._乘客们.数量)
{
return this._乘客们[当前第几个];
}
else
{
return null;
}
}
public override bool IsDone()
{
return this.当前第几个 >= this._乘客们.数量;
}
}
internal class Program
{
static void Main(string[] args)
{
车上的乘客 隧道六线 = new 车上的乘客();
隧道六线.上车("张三");
隧道六线.上车("李四");
隧道六线.上车("王五");
隧道六线.上车("赵六");
Iterator iterator = 隧道六线.CreateIterator();
while (!iterator.IsDone())
{
Console.WriteLine("{0},请你买票,谢谢!", iterator.CurrentItem());
iterator.Next();
}
Console.ReadLine();
}
}
}
<1>访问一个聚合对象的内容而无需暴露它的内部表示。
<2>支持对聚合对象的多种遍历。
<3>为遍历不同的聚合结构提供一个统一的接口(即,支持多态迭代)。
namespace Test
{
///
/// 聚合对象(集合)
///
public abstract class Aggregate
{
public abstract Iterator CreateIterator();
}
///
/// 迭代器:能遍历一个集合的遍历行为
///
public abstract class Iterator
{
public abstract object First();
public abstract void Next();
public abstract object Current();
public abstract bool IsDone
{
get;
}
}
///
/// 一年级
///
public class FirstGrade : Aggregate
{
public override Iterator CreateIterator()
{
//return new FirstGradeAsceIterator(this);
return new FirstGradeDeAsceIterator(this);
}
private List<Student> students = new List<Student>();
public void AddStudent(Student student)
{
this.students.Add(student);
}
public int StudentsCount
{
get { return this.students.Count; }
}
public Student this[int index]
{
get { return this.students[index]; }
}
}
public class Student
{
public Student(string name)
{
this.Name = name;
}
public string Name { get; set; }
public override string ToString()
{
return this.Name;
}
}
///
/// 按照升序迭代
///
public class FirstGradeAsceIterator : Iterator
{
///
/// 关联到需要迭代的一年级班级(集合)
///
private FirstGrade? myClass = null;
///
/// 对班级的依赖
///
///
public FirstGradeAsceIterator(FirstGrade myClassToIterator)
{
this.myClass = myClassToIterator;
}
private int currentIndex = 0;
public override object Current()
{
return this.myClass[this.currentIndex];
}
public override object First()
{
return this.myClass[0];
}
public override void Next()
{
this.currentIndex++;
}
public override bool IsDone
{
get
{
return this.currentIndex == this.myClass.StudentsCount;
}
}
}
///
/// 按照降序迭代
///
public class FirstGradeDeAsceIterator : Iterator
{
///
/// 关联到需要迭代的一年级班级(集合)
///
private FirstGrade? myClass = null;
private int currentIndex;
///
/// 对班级的依赖
///
///
public FirstGradeDeAsceIterator(FirstGrade myClassToIterator)
{
this.myClass = myClassToIterator;
currentIndex = myClass.StudentsCount - 1;
}
public override object Current()
{
return this.myClass[this.currentIndex];
}
public override object First()
{
return this.myClass[myClass.StudentsCount - 1];
}
public override void Next()
{
this.currentIndex--;
}
public override bool IsDone
{
get
{
return this.currentIndex == -1;
}
}
}
internal class Program
{
static void Main(string[] args)
{
FirstGrade firstGrade = new FirstGrade();
firstGrade.AddStudent(new Student("张三"));
firstGrade.AddStudent(new Student("李四"));
firstGrade.AddStudent(new Student("王五"));
Iterator iterator = (firstGrade as Aggregate).CreateIterator();
while (!iterator.IsDone)
{
object current = iterator.Current();
Console.WriteLine(current);
iterator.Next();
}
Console.ReadLine();
}
}
}
namespace Test
{
///
/// 聚合对象(集合)
///
public abstract class Aggregate
{
public abstract Iterator CreateIterator();
}
///
/// 迭代器:能遍历一个集合的遍历行为
///
public abstract class Iterator
{
public abstract object First();
public abstract void Next();
public abstract object Current();
public abstract bool IsDone
{
get;
}
}
///
/// 一年级
///
public class FirstGrade : Aggregate
{
public override Iterator CreateIterator()
{
return new FirstGradeAsceIterator(this);
//return new FirstGradeDeAsceIterator(this);
}
private List<Student> students = new List<Student>();
public void AddStudent(Student student)
{
this.students.Add(student);
}
///
/// 按照升序迭代
///
private class FirstGradeAsceIterator : Iterator
{
///
/// 关联到需要迭代的一年级班级(集合)
///
private FirstGrade? myClass = null;
///
/// 对班级的依赖
///
///
public FirstGradeAsceIterator(FirstGrade myClassToIterator)
{
this.myClass = myClassToIterator;
}
private int currentIndex = 0;
public override object Current()
{
return this.myClass.students[this.currentIndex];
}
public override object First()
{
return this.myClass.students[0];
}
public override void Next()
{
this.currentIndex++;
}
public override bool IsDone
{
get
{
return this.currentIndex == this.myClass.students.Count;
}
}
}
///
/// 按照降序迭代
///
private class FirstGradeDeAsceIterator : Iterator
{
///
/// 关联到需要迭代的一年级班级(集合)
///
private FirstGrade? myClass = null;
private int currentIndex;
///
/// 对班级的依赖
///
///
public FirstGradeDeAsceIterator(FirstGrade myClassToIterator)
{
this.myClass = myClassToIterator;
currentIndex = myClass.students.Count - 1;
}
public override object Current()
{
return this.myClass.students[this.currentIndex];
}
public override object First()
{
return this.myClass.students[myClass.students.Count - 1];
}
public override void Next()
{
this.currentIndex--;
}
public override bool IsDone
{
get
{
return this.currentIndex == -1;
}
}
}
}
public class Student
{
public Student(string name)
{
this.Name = name;
}
public string Name { get; set; }
public override string ToString()
{
return this.Name;
}
}
internal class Program
{
static void Main(string[] args)
{
FirstGrade firstGrade = new FirstGrade();
firstGrade.AddStudent(new Student("张三"));
firstGrade.AddStudent(new Student("李四"));
firstGrade.AddStudent(new Student("王五"));
Iterator iterator = (firstGrade as Aggregate).CreateIterator();
while (!iterator.IsDone)
{
object current = iterator.Current();
Console.WriteLine(current);
iterator.Next();
}
Console.ReadLine();
}
}
}
using System.Collections;
using System.Collections.Generic;
namespace Test
{
public class 车上的乘客NET : System.Collections.IEnumerable
{
private System.Collections.ArrayList al = new System.Collections.ArrayList();
public void 上车(string 乘客姓名)
{
this.al.Add(乘客姓名);
}
public string this[int index]
{
get { return this.al[index].ToString(); }
}
public int 数量
{
get { return this.al.Count; }
}
#region IEnumerable 成员
public System.Collections.IEnumerator GetEnumerator()
{
return new ConcreteIteratorNET(this);
}
#endregion
}
public class 车上的乘客NET2 : System.Collections.IEnumerable
{
private System.Collections.ArrayList al = new System.Collections.ArrayList();
public void 上车(string 乘客姓名)
{
this.al.Add(乘客姓名);
}
#region IEnumerable 成员
public System.Collections.IEnumerator GetEnumerator()
{
foreach (object var in this.al)
{
yield return var;
}
}
#endregion
}
public class ConcreteIteratorNET : System.Collections.IEnumerator
{
private 车上的乘客NET _乘客们 = null;
private int 当前第几个 = -1;
public ConcreteIteratorNET(车上的乘客NET 乘客)
{
this._乘客们 = 乘客;
}
#region IEnumerator 成员
public object Current
{
get { return this._乘客们[当前第几个]; }
}
public bool MoveNext()
{
this.当前第几个++;
return this.当前第几个 < this._乘客们.数量;
}
public void Reset()
{
this.当前第几个 = -1;
}
#endregion
}
internal class Program
{
static void Main(string[] args)
{
车上的乘客NET 隧道六线 = new 车上的乘客NET();
隧道六线.上车("张三");
隧道六线.上车("李四");
隧道六线.上车("王五");
隧道六线.上车("赵六");
System.Collections.IEnumerator iterator = 隧道六线.GetEnumerator();
while (iterator.MoveNext())
{
Console.WriteLine("{0},请你买票,谢谢!", iterator.Current);
}
Console.ReadLine();
}
}
}
<1>迭代抽象:访问一个聚合对象的内容而无需暴露它的内部表示。
<2>迭代多态:为遍历不同的集合结构提供一个统一的接口,从而支持同样的算法在不同的集合结构上进行操作。
<3>迭代器的健壮性考虑:遍历的同时更改迭代器所在的集合结构,会导致问题。