翻译:在我们使用的NET FRAMEWORK类库中发现设计模式(3)
迭代器模式(Iterator Pattern)
许多编程的任务都是操作集合。无论是简单的对象列表还是复杂的B-Tree集合,我们都需要经常访问集合里的元素,我们经常通过一些方法来访问这些集合中的元素,例如从前到后,从后到前,或者正序或者倒序访问。
一个最常见的基本方法之一就是将对象列表存储的数组里,数组类型已经内置在VB.NET与C#语言里了,它们都有对数组元素进行枚举的循环结构:在C#里是Foreach,在VB.NET里是For Eeah。这里有一个枚举数组的例子:
int[] values = new int[] {1, 2, 3, 4, 5};
foreach(int i in values)
{
Console.Write(i.ToString() + " ");
}
这些语句会在内部使用一个迭代器,你所能知道的是确信能将数组中的元素在每一次循环中枚举出来。
为了让这些语句能正常执行,在表达式中数组对象必须实现IEnumerable,所有实现了IEnumerable对象集合类都能够遍历(也就是枚举),IEnumerable接口有一个方法:GetEnumerator,这个方法能返回一个实现了IEnumerator的类型,这个实现了IEnumerator的类型能够对这个集合进行枚举。它有一个Current的属性,并且有能够从头到尾的向前枚举集合中元素的方法—MoveNext和Rest,这些对象集合类都System.Collections名称空间里,这些集合类和数组一样,实现了IEnumerable接口凭此来枚举集合中的元素。
如果你查看一下C#编译器生成的使用Foreach语句的中间语言MSIL(Microsoft intermediate language),你会发现大多数的集合类都采用枚举器来进行枚举。下面有一个使用 IEnumerator方式来进行枚举的例子,它与前面的那个例子实现了同样的功能:
int[] values = new int[] {1, 2, 3, 4, 5};
IEnumerator e = ((IEnumerable)values).GetEnumerator();
while(e.MoveNext())
{
Console.Write(e.Current.ToString() + " ");
}
.NET Framework使用IEnumerable和IEnumerator来应用迭代器模式,迭代器模式让你很轻松的遍历一个集合而不需要集合来展示自己内部的处理过程。实现了IEnumerator的迭代类从实现了IEnumerable的集合类中分离开来,这个类负责来处理枚举的状态(包括怎么表达当前数组中的元素和如何迭代集合中的元素),并把枚举的算法包含其中。这种方法能让你同时有几个用不同的方法枚举集合的迭代器,而不需要给集合添加任何的复杂性!
装饰模式(Decorator Pattern)
有效的可执行程序不但包括读入与写出或者全部,无论读写的资源来源于哪里,资源都会被抽象的认作为字节流, .NET使用System.IO.Stream 类来表达这种抽象,不管它来源于文本文件,TCP/IP网络通信或者是其他的实体,文件数据类(FileStream)和网络通信类(NetworkStrem)都继承了Stream类,你可以轻松的处理这些数据而不管这些数据的来源,下面是一个将流中的字节输出到控制台的方法:
public static void PrintBytes(Stream s)
{
int b;
while((b = fs.ReadByte()) >= 0)
{