迭代器模式(Iterator Pattern)
2006-10-22 16:55
295 查看
面向对象的设计,要求为对象做到好的职责分离,每个对象只包括最少的职责,这样其与其他对象的联系也越少,降低了对象间的耦合度。职责分离需要对对象被分离的职责进行封装,并以抽象的方式建立起彼此之间的关系。在设计中,我们往往将这些可能变化的对象抽象为接口和抽象类,从而将原来的具体依赖改变为抽象依赖。
迭代器模式就是分离集合对象的职责的方法,其将集合对象存储数据(存储数据的类型、存储空间的大小、存储空间的分配等)和顺序访问数据这二种职责进行分离。
目的:
提供一种方法顺序访问一个聚合对象中各个元素, 而又不需暴露该对象的内部表示。
适用性:
访问一个聚合对象的内容而无需暴露它的内部表示。
支持对聚合对象的多种遍历。
为遍历不同的聚合结构提供一个统一的接口(即, 支持多态迭代)。
C#典型实现:
在.Net中,迭代器由IEnumerator接口所定义:
public interface IEnumerator
...{
bool MoveNext();
Object Current ...{get; }
void Reset();
}
该接口提供了遍历集合元素的方法,其中主要的方法是MoveNext()。它将集合中的元素下标移到下一个元素。如果集合中没有元素,或已经移到了最后一个,则返回false。能够提供元素遍历的集合对象,在.Net中都实现了IEnumerator接口。
而.Net中的所有集合类则实现另一个接口IEnumerable,其定义如下:
public interface IEnumerable
...{
IEnumerator GetEnumerator();
}
GetEnumerator()方法是一个生成迭代器的工厂方法,在集合类的内部以内部类的方式定义一个实现了IEnumerator接口的迭代器类,并在GetEnumerator()方法中返回其迭代器类的一个实例。
下面是.Net中的ArrayList的实现示意类图:
其中,类ArrayListEnumeratorSimple的相关实现如下所示:
[Serializable]
private class ArrayListEnumeratorSimple : IEnumerator, ICloneable
...{
// Methods
internal ArrayListEnumeratorSimple(ArrayList list)
...{
this.list = list;
this.index = -1;
this.version = list._version;
this.currentElement = list;
}
public virtual bool MoveNext()
...{
if (this.version != this.list._version)
...{
throw new InvalidOperationException(Environment.GetResourceString(”InvalidOperation_EnumFailedVersion”));
}
if (this.index < (this.list.Count - 1))
...{
this.index++;
this.currentElement = this.list[this.index];
return true;
}
this.currentElement = this.list;
this.index = this.list.Count;
return false;
}
public virtual void Reset()
...{
if (this.version != this.list._version)
...{
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_EnumFailedVersion"));
}
this.currentElement = this.list;
this.index = -1;
}
// Properties
public virtual object Current
...{
get
...{
object obj1 = this.currentElement;
if (obj1 != this.list)
...{
return obj1;
}
if (this.index == -1)
...{
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_EnumNotStarted"));
}
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_EnumEnded"));
}
}
// Fields
private object currentElement;
private int index;
private ArrayList list;
private int version;
}
ArrayListEnumeratorSimple实现了IEnumerator接口,实现了MoveNext()、Current、Reset ()方法或属性。该类是一个私有类型,其构造函数则被internal修饰符限制。在自定义的构造函数中,传入的参数类型是ArrayList。正是通过 构造函数传递需要遍历的ArrayList对象,来完成MoveNext()、Current、Reset()等操作。
在ArrayList中,IEnumerable接口的GetEnumerator()方法实现代码如下:
public virtual IEnumerator GetEnumerator()
...{
return new ArrayListEnumeratorSimple(this);
}
.Net2.0的实现:
由于在.Net2.0中对迭代器的实现提供了直接支持,所以其实现更加简单,并且不需要实现IEnumerable:
public IEnumerator GetEnumerator()
...{
for(int i = 0 ; i < Count ; i ++ )
yield return this[ i ] ;
}
但.Net2.0的编译器最终会将其编译成类似典型实现的代码,只不过我们不需要再去手工实现IEnumerator接口。
迭代器模式就是分离集合对象的职责的方法,其将集合对象存储数据(存储数据的类型、存储空间的大小、存储空间的分配等)和顺序访问数据这二种职责进行分离。
目的:
提供一种方法顺序访问一个聚合对象中各个元素, 而又不需暴露该对象的内部表示。
适用性:
访问一个聚合对象的内容而无需暴露它的内部表示。
支持对聚合对象的多种遍历。
为遍历不同的聚合结构提供一个统一的接口(即, 支持多态迭代)。
C#典型实现:
在.Net中,迭代器由IEnumerator接口所定义:
public interface IEnumerator
...{
bool MoveNext();
Object Current ...{get; }
void Reset();
}
该接口提供了遍历集合元素的方法,其中主要的方法是MoveNext()。它将集合中的元素下标移到下一个元素。如果集合中没有元素,或已经移到了最后一个,则返回false。能够提供元素遍历的集合对象,在.Net中都实现了IEnumerator接口。
而.Net中的所有集合类则实现另一个接口IEnumerable,其定义如下:
public interface IEnumerable
...{
IEnumerator GetEnumerator();
}
GetEnumerator()方法是一个生成迭代器的工厂方法,在集合类的内部以内部类的方式定义一个实现了IEnumerator接口的迭代器类,并在GetEnumerator()方法中返回其迭代器类的一个实例。
下面是.Net中的ArrayList的实现示意类图:
其中,类ArrayListEnumeratorSimple的相关实现如下所示:
[Serializable]
private class ArrayListEnumeratorSimple : IEnumerator, ICloneable
...{
// Methods
internal ArrayListEnumeratorSimple(ArrayList list)
...{
this.list = list;
this.index = -1;
this.version = list._version;
this.currentElement = list;
}
public virtual bool MoveNext()
...{
if (this.version != this.list._version)
...{
throw new InvalidOperationException(Environment.GetResourceString(”InvalidOperation_EnumFailedVersion”));
}
if (this.index < (this.list.Count - 1))
...{
this.index++;
this.currentElement = this.list[this.index];
return true;
}
this.currentElement = this.list;
this.index = this.list.Count;
return false;
}
public virtual void Reset()
...{
if (this.version != this.list._version)
...{
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_EnumFailedVersion"));
}
this.currentElement = this.list;
this.index = -1;
}
// Properties
public virtual object Current
...{
get
...{
object obj1 = this.currentElement;
if (obj1 != this.list)
...{
return obj1;
}
if (this.index == -1)
...{
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_EnumNotStarted"));
}
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_EnumEnded"));
}
}
// Fields
private object currentElement;
private int index;
private ArrayList list;
private int version;
}
ArrayListEnumeratorSimple实现了IEnumerator接口,实现了MoveNext()、Current、Reset ()方法或属性。该类是一个私有类型,其构造函数则被internal修饰符限制。在自定义的构造函数中,传入的参数类型是ArrayList。正是通过 构造函数传递需要遍历的ArrayList对象,来完成MoveNext()、Current、Reset()等操作。
在ArrayList中,IEnumerable接口的GetEnumerator()方法实现代码如下:
public virtual IEnumerator GetEnumerator()
...{
return new ArrayListEnumeratorSimple(this);
}
.Net2.0的实现:
由于在.Net2.0中对迭代器的实现提供了直接支持,所以其实现更加简单,并且不需要实现IEnumerable:
public IEnumerator GetEnumerator()
...{
for(int i = 0 ; i < Count ; i ++ )
yield return this[ i ] ;
}
但.Net2.0的编译器最终会将其编译成类似典型实现的代码,只不过我们不需要再去手工实现IEnumerator接口。
相关文章推荐
- 设计模式:迭代器模式(Iterator Pattern)
- 迭代器模式(Iterator Pattern)
- 设计模式之九:迭代器模式(Iterator Pattern)
- 迭代器模式(Iterator Pattern)
- 迭代器模式【Iterator Pattern】
- Php设计模式之【迭代器模式Iterator Pattern】
- Net设计模式实例之迭代器模式(Iterator Pattern)(2) 推荐
- 乐在其中设计模式(C#) - 迭代器模式(Iterator Pattern)
- 解读设计模式----迭代器模式(Iterator Pattern) 推荐
- 迭代器模式(Iterator Pattern)
- 迭代器模式(Iterator Pattern)
- 设计模式-迭代器模式(iterator pattern)
- 16.迭代器模式(Iterator Pattern)
- java设计模式---迭代器模式(iterator pattern)
- 十九.行为型设计模式——Iterator Pattern(迭代器模式)
- 【23种设计模式】之 迭代器模式(Iterator Pattern)
- .NET设计模式(18):迭代器模式(Iterator Pattern)
- 设计模式(C#)之迭代器模式(Iterator Pattern)
- 迭代器模式iterator pattern
- 迭代器模式(Iterator Pattern)(转自TerryLee)