C# 设计模式-迭代模式
一.介绍
迭代模式(Iterator Pattern)。属于行为型模式。它提供一种方法顺序访问聚合对象中各个元素,而又不暴露该对象的内部表示。
二.实现
迭代模式是针对聚合对象使用的,一般使用聚合,有增删改操作,也需要进行遍历操作。如果聚合对象全实现这些功能,那根据单一职责原则,聚合对象就承担了太多责任。迭代模式就是去实现遍历聚合对象责任的方式,通俗理解,就是建立一个迭代类,这个包含了整个聚合对象,由这个迭代类记录当前聚合的当前位置以及去遍历查询这个聚合。下面实现的是标准的迭代器模式。
//抽象迭代器类 public abstract class Iterator { public abstract object First(); public abstract object Next(); public abstract bool IsEnd(); public abstract object CurrentItem(); } //具体迭代器类 public class ConcreteIterator : Iterator { ConcreteAggregate list; int position = -1; public ConcreteIterator(ConcreteAggregate aggregate) { this.list = aggregate; position = 0; } public override object CurrentItem() { if (position >= 0 && position < list.Count) { return list[position]; } throw new IndexOutOfRangeException(); } public override object First() { return list[0]; } public override bool IsEnd() { return position >= list.Count - 1; } public override object Next() { ++position; if (position < list.Count) { return list[position]; } throw new IndexOutOfRangeException(); } } //抽象聚合类 public abstract class Aggregate { public abstract Iterator GetIterator(); } //具体聚合类 public class ConcreteAggregate : Aggregate { List<int> _items = new List<int>(); public ConcreteAggregate() { } public override Iterator GetIterator() { return new ConcreteIterator(this); } public int Count { get { return _items.Count(); } } public int this[int index] { get { return _items[index]; } set { _items.Add(value); } } } //调用 public static void Main(string[] args) { var arr = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; var aggregate = new ConcreteAggregate(); int index = 0; foreach (var i in arr) { aggregate[index] = i; index++; } var iterator = aggregate.GetIterator(); Console.WriteLine(iterator.First()); while (!iterator.IsEnd()) { var i = iterator.Next(); Console.WriteLine(i); } }
在C#中,迭代模式的聚合接口和迭代器接口都已经存在,其中IEnumerator接口是迭代器角色,IEnumberable接口是抽象聚合角色。
public class Person : IEnumerable<string> { string[] persons; public Person(string[] persons) { this.persons = persons; } public IEnumerator<string> GetEnumerator() { return new PersonIEnumerator(persons); } IEnumerator IEnumerable.GetEnumerator() { return new PersonIEnumerator(persons); } } public class PersonIEnumerator : IEnumerator<string> { private int position = -1; private string[] items; public PersonIEnumerator(string[] items) { this.items = items; } public string Current { get { return items[position]; } } object IEnumerator.Current => Current; public void Dispose() { } public bool MoveNext() { ++position; return position < items.Length; } public void Reset() { position = -1; } } //调用 public static void Main(string[] args) { Person person = new Person(new string[] { "甲", "乙", "丙", "丁" }); Console.WriteLine("foreach demo:"); foreach (var p in person) { Console.WriteLine(p); } Console.WriteLine(); var ienumerator = person.GetEnumerator(); Console.WriteLine("MoveNext demo:"); while (ienumerator.MoveNext()) { Console.WriteLine(ienumerator.Current); } }
三.总结
优点:
1.迭代模式使得访问一个聚合对象的内容而不用暴露它的内部表示,即迭代抽象。
2.迭代模式为遍历不同的聚合结构提供了一个统一的接口,从而支持了不同聚合结构可以使用同样的算法。
缺点:
1.迭代模式使得在遍历时更改聚合对象会出现异常,所以使用foreach语句只能进行遍历,不能在遍历时进行修改聚合中元素操作。