[Head First设计模式]生活中学设计模式——迭代器模式
系列文章
[Head First设计模式]山西面馆中的设计模式——装饰者模式
[Head First设计模式]山西面馆中的设计模式——观察者模式
[Head First设计模式]山西面馆中的设计模式——建造者模式
[Head First设计模式]饺子馆(冬至)中的设计模式——工厂模式
[Head First设计模式]抢票中的设计模式——代理模式
[Head First设计模式]云南米线馆中的设计模式——模版方法模式
[Head First设计模式]餐馆中的设计模式——命令模式
[Head First设计模式]身边的设计模式——适配器模式
迭代器模式
提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的表示。
类图
角色
Iterator:定义访问和遍历元素的接口
Concretelterator:具体迭代器,实现迭代器接口,对该聚合遍历时跟踪当前位置。
Aggregate:聚合,定义创建相应迭代器对象的接口。
ConcreteAggregate:具体聚合,其工作是实现相应迭代器的接口,返回具体迭代器的一个适当的实例。
适用场景
1,访问一个聚合对象的内容而无需暴露它的内部表示
2,支持对聚合对象的多种遍历
3,为遍历不同的聚合结构提供一个统一的接口(即支持多态迭代)
优缺点
优点:
1,支持以不同的方式遍历一个聚合
2,简化了聚合的接口
3,可同时进行多个遍历
缺点:
和集合密切相关,限制了其广泛使用。
一个例子
公共汽车售票员工作的场景:
售票员不管上来的是人还是行李,不管是中国人还是外国人,不管是内部员工还是别的,只要是来乘车的乘客,就必须要买票。也就是说,当我们需要访问一个聚集对象,而且不管这些对象是什么都需要遍历的时候,就应该考虑用迭代模式。
另外,售票员从车头到车尾来售票,也可以从车尾向车头来售票,也就是说,当我们需要对聚集有很多种方式遍历时,可以考虑用迭代器模式。
由于不管乘客是什么,售票员的做法始终是相同的,都是从第一个开始,下一个,是否结束,当前售到那一个人,这些方法每天他都在做,也就是说,当遍历不同的聚集结构提供如开始、下一个、是否结束、当前哪一项等统一的过程,可以考虑使用迭代器模式。
这里使用IEnumerator,.net中的迭代器接口
1 namespace System.Collections 2 { 3 // 摘要: 4 // 支持对非泛型集合的简单迭代。 5 [ComVisible(true)] 6 [Guid("496B0ABF-CDEE-11d3-88E8-00902754C43A")] 7 public interface IEnumerator 8 { 9 // 摘要: 10 // 获取集合中的当前元素。 11 // 12 // 返回结果: 13 // 集合中的当前元素。 14 object Current { get; } 15 16 // 摘要: 17 // 将枚举数推进到集合的下一个元素。 18 // 19 // 返回结果: 20 // 如果枚举数成功地推进到下一个元素,则为 true;如果枚举数越过集合的结尾,则为 false。 21 // 22 // 异常: 23 // System.InvalidOperationException: 24 // 在创建了枚举数后集合被修改了。 25 bool MoveNext(); 26 // 27 // 摘要: 28 // 将枚举数设置为其初始位置,该位置位于集合中第一个元素之前。 29 // 30 // 异常: 31 // System.InvalidOperationException: 32 // 在创建了枚举数后集合被修改了。 33 void Reset(); 34 } 35 }
Concretelterator:具体迭代器,实现迭代器接口,对该聚合遍历时跟踪当前位置。
1 namespace Wolfy.迭代器模式 2 { 3 public class Concretelterator : IEnumerator 4 { 5 private ConcreteAggregate aggregate; 6 private int currentIndex=-1; 7 public Concretelterator(ConcreteAggregate aggregate) 8 { 9 this.aggregate = aggregate; 10 } 11 public object Current 12 { 13 get { return aggregate[currentIndex]; } 14 } 15 16 public bool MoveNext() 17 { 18 currentIndex++; 19 return currentIndex < this.aggregate.Count; 20 21 } 22 23 public void Reset() 24 { 25 currentIndex = -1; 26 } 27 } 28 }
1 namespace Wolfy.迭代器模式 2 { 3 public abstract class Aggregate 4 { 5 public abstract IEnumerator CreateEnumerator(); 6 } 7 }
ConcreteAggregate:具体聚合,其工作是实现相应迭代器的接口,返回具体迭代器的一个适当的实例。
1 namespace Wolfy.迭代器模式 2 { 3 public class ConcreteAggregate : Aggregate 4 { 5 private ArrayList arr=new ArrayList(); 6 public int Count 7 { 8 get { return arr.Count; } 9 } 10 public object this[int index] 11 { 12 get { return arr[index]; } 13 set { arr.Insert(index, value); } 14 } 15 public override System.Collections.IEnumerator CreateEnumerator() 16 { 17 return new Concretelterator(this); 18 } 19 } 20 }
测试
1 namespace Wolfy.迭代器模式 2 { 3 class Program 4 { 5 static void Main(string[] args) 6 { 7 8 ConcreteAggregate agg = new ConcreteAggregate(); 9 agg[0] = "乘客1"; 10 agg[1] = "乘客2"; 11 agg[2] = "乘客3"; 12 agg[3] = "乘客4"; 13 agg[4] = "乘客5"; 14 agg[5] = "乘客6"; 15 agg[6] = "乘客7"; 16 agg[7] = "乘客8"; 17 agg[8] = "乘客9"; 18 agg[9] = "乘客10"; 19 IEnumerator iterator =agg.CreateEnumerator(); 20 while (iterator.MoveNext()) 21 { 22 Console.WriteLine(iterator.Current); 23 } 24 iterator.Reset(); 25 Console.Read(); 26 } 27 } 28 }
结果:
总结
这个模式给你提供了一种方法,可以顺序访问一个聚集对象中的元素,而又不用知道内部是如何表示的。
参考书:
《Head First 设计模式》