您的位置:首页 > 移动开发 > Objective-C

迭代器模式(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接口。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息