一、目的
提供一种方法访问一个容器对象中各个元素,而又不需暴露该对象的内部细节。
二、定义
迭代器模式提供了一种方法访问一个聚合对象(理解为集合对象)中各个元素,而又无需暴露该对象的内部表示,这样既可以不对外暴露内部结构,同时也可让外部代码透明地访问集合内部的数据。
三、场景
假设我们有一个自定义的集合数据,以下我们将采用迭代器模式来遍历这个集合。
四、实现
1 using System; 2 using System.Collections.Generic; 3 4 namespace DesignMode_Iterator 5 { 6 public interface IListCollection 7 { 8 IIterator GetIterator(); 9 } 10 11 public interface IIterator 12 { 13 bool MoveNext(); 14 Object GetCurrent(); 15 void Next(); 16 void Reset(); 17 } 18 19 public class ConcreteList : IListCollection 20 { 21 int[] collection; 22 public ConcreteList() 23 { 24 collection = new int[] { 2, 4, 5, 8, 10, 12, 14 }; 25 } 26 public IIterator GetIterator() 27 { 28 return new ConcreteIterator(this); 29 } 30 public int Length 31 { 32 get 33 { 34 return collection.Length; 35 } 36 } 37 public int GetElement(int index) 38 { 39 return collection[index]; 40 } 41 } 42 43 public class ConcreteIterator : IIterator 44 { 45 private ConcreteList _list; 46 private int _index; 47 public ConcreteIterator(ConcreteList list) 48 { 49 this._list = list; 50 _index = 0; 51 } 52 53 public bool MoveNext() 54 { 55 if (_index < _list.Length) 56 { 57 return true; 58 } 59 return false; 60 } 61 public Object GetCurrent() 62 { 63 return _list.GetElement(_index); 64 } 65 public void Reset() 66 { 67 _index = 0; 68 } 69 public void Next() 70 { 71 if (_index < _list.Length) 72 { 73 _index++; 74 } 75 } 76 } 77 class Program 78 { 79 static void Main(string[] args) 80 { 81 List<int> a = new List<int>(); 82 83 IIterator iterator; 84 IListCollection list = new ConcreteList(); 85 iterator = list.GetIterator(); 86 while (iterator.MoveNext()) 87 { 88 int i = (int)iterator.GetCurrent(); 89 Console.Write(i.ToString() + " "); 90 iterator.Next(); 91 } 92 Console.WriteLine(); 93 } 94 } 95 }
运行结果如下:
五、类图
六、描述
从上图可以看出,迭代器模式主要由以下角色组成:
(1)迭代器角色(Iterator):迭代器角色负责定义访问和遍历元素的接口。
(2)具体迭代器角色(Concrete Iteraror):具体迭代器角色实现了迭代器接口,并需要记录遍历中的当前位置。
(3)聚合角色(Aggregate):聚合角色负责定义获得迭代器角色的接口。
(4)具体聚合角色(Concrete Aggregate):具体聚合角色实现聚合角色接口。
七、在.Net中的应用
在.NET下,迭代器模式中的聚集接口和迭代器接口都已经存在了,其中IEnumerator接口扮演的就是迭代器角色,IEnumberable接口则扮演的就是抽象聚集的角色,只有一个GetEnumerator()方法,关于这两个接口的定义可以自行参考MSDN。在.NET 1.0中,.NET 类库中很多集合都已经实现了迭代器模式,大家可以用反编译工具Reflector来查看下mscorlib程序集下的System.Collections命名空间下的类,这里给出ArrayList的定义代码,具体实现代码可以自行用反编译工具查看,具体代码如下所示:
1 public class ArrayList : IList, ICollection, IEnumerable, ICloneable 2 { 3 // Fields 4 private const int _defaultCapacity = 4; 5 private object[] _items; 6 private int _size; 7 [NonSerialized] 8 private object _syncRoot; 9 private int _version; 10 private static readonly object[] emptyArray; 11 12 public virtual IEnumerator GetEnumerator(); 13 public virtual IEnumerator GetEnumerator(int index, int count); 14 15 // Properties 16 public virtual int Capacity { get; set; } 17 public virtual int Count { get; } 18 ..............// 更多代码请自行用反编译工具Reflector查看 19 }