设计模式(十六)迭代器模式

迭代器模式(Iterator),提供一种方法顺序访问一个聚合对象中各个元素,而又不暴露该对象的内部表示。迭代器模式为遍历不同的聚集结构提供如开始、下一个、是否结束、当前哪一项等统一的接口。

.NET 框架中 IEnumerator 支持对 非泛型集合 的简单迭代接口。

 1 public interface IEnumerator
 2 {
 3   object Current
 4   {
 5     get;   // 获取集合中的当前元素
 6   }
 7   // 将枚举数推进到集合的下一个元素。方法返回值 true 表示迭代器成功前进道集合中的下一个元素,返回值 false 表示已经位于集合的末尾
 8   bool MoveNext();
 9 
10   // 恢复初始化指向的位置,该位置位于集合中第一个元素之前
11   void Reset();
12 }
13 
14 // 公开枚举数,该枚举数支持在非泛型集合上进行简单迭代
15 public interface IEnumerable
16 {
17   // 返回一个循环访问集合的枚举数
18   IEumerator GetEnumerator(); 
19 }

foreach(string item in a) 的内部实现

1 IEnumerator<string> e = a.GetEnumerator();
2 
3 while(e.MoveNext())
4 {
5   Console.WriteLine("{0}", e.Current);
6 }

 

 

 基本代码

  1 // 迭代器抽象类,用于定义得到开始对象、下一个对象;判断是否到结尾、当前对象等抽象方法,统一接口
  2 abstract class Iterator
  3 {
  4   public abstract object First();
  5   public abstract object Next();
  6   public abstract bool IsDone();
  7   public abstract object CurrentItem();
  8 }
  9 
 10 // 聚集抽象类,创建迭代器
 11 abstract class Aggregate
 12 {
 13   public abstract Iterator CreateIterator();
 14 }
 15 
 16 // 具体聚集类
 17 class ConcreteAggregate : Aggregate
 18 {
 19   // 声明一个 IList 泛型变量,用于存放聚合对象,用 ArrayList 同样可以实现
 20   private IList<object> items = new List<object>();
 21 
 22   public override Iterator CreateIterator()
 23   {
 24     return new  ConcreteIterator(this);
 25   }
 26 
 27   // 返回聚集总个数
 28   public int Count
 29   {
 30     get { return items.Count; }
 31   }
 32 
 33   // 声明一个索引器
 34   public object this[this index]
 35   {
 36     get { return items[index]; }
 37     set { items.Insert(index, value); }
 38   }
 39 }
 40 
 41 // 具体迭代器类
 42 class ConcreteIterator : Iterator
 43 {
 44   // 定义一个具体聚集对象
 45   private ConcreteAggregate aggregate;
 46   private int current = 0;
 47 
 48   // 初始化时将具体的聚类对象传入
 49   public ConcreteIterator(ConcreteAggregate aggregate)
 50   {
 51     this.aggregate = aggregate;
 52   }
 53 
 54   // 得到聚集的第一个对象
 55   public override object First()
 56   {
 57     return aggregate[0];
 58   }
 59 
 60   // 得到聚集的下一个对象
 61   public override object Next()
 62   {
 63     object ret = null;
 64     current++;
 65     if(current < aggregate.Count)
 66     {
 67       ret = aggregate[current];
 68     }
 69     return ret;
 70   }
 71 
 72   // 判断当前是否遍历到结尾
 73   public override bool IsDone()
 74   {
 75     return current >= aggregate.Count ? true : false;
 76   }
 77 
 78   // 返回当前的聚集对象
 79   public override object CurrentItem()
 80   {
 81     return aggregate[current];
 82   }
 83 }
 84 
 85 // 实现从后向前反向遍历的具体迭代器类
 86 class ConcreteIteratorDesc : Iterator
 87 {
 88   // 定义一个具体聚集对象
 89   private ConcreteAggregate aggregate;
 90   private int current = 0;
 91 
 92   // 初始化时将具体的聚类对象传入
 93   public ConcreteIteratorDesc(ConcreteAggregate aggregate)
 94   {
 95     this.aggregate = aggregate;
 96     current = aggregate.Count -1;
 97   }
 98 
 99   // 得到聚集的第一个对象
100   public override object First()
101   {
102     return aggregate[aggregate.Count -1];
103   }
104 
105   // 得到聚集的下一个对象
106   public override object Next()
107   {
108     object ret = null;
109     current--;
110     if(current >= 0)
111     {
112       ret = aggregate[current];
113     }
114     return ret;
115   }
116 
117   // 判断当前是否遍历到结尾
118   public override bool IsDone()
119   {
120     return current < 0 ? true : false;
121   }
122 
123   // 返回当前的聚集对象
124   public override object CurrentItem()
125   {
126     return aggregate[current];
127   }
128 }
129 
130 // 客户端
131 static void Main(string[] args)
132 {
133   // 聚集对象
134   ConcreteAggregate a = new ConcreteAggregate();
135   a[0] = "1";
136   a[1] = "2";
137   a[2] = "3";
138 
139   // 声明迭代器对象
140   Iterator i = new ConcreteIterator(a);
141   //Iterator i = new ConcreteIteratorDesc(a);
142 
143   object item = i.First();
144   while(!i.IsDone())
145   {
146     Console.WriteLine();
147     i.Next();
148   }
149 
150   Console.Read();
151 } 

【总结】

迭代器(Iterator)模式就是分离了集合对象的遍历行为,抽象出一个迭代器类来负责,这样既可以做到不暴露集合的内部结构,又可以让外部代码透明地访问集合内部的数据。迭代器模式在访问数组、集合、列表等数据时,尤其是数据库操作时,是非常普遍的应用。

posted @ 2015-06-20 12:31  壬子木  阅读(102)  评论(0)    收藏  举报