意图 intent :提供一种方法顺序访问一个聚合对象中各个元素 , 而又不需暴露该对象的内部表示。
适用性:
访问一个聚合对象的内容而无需暴露它的内部表示。
支持对聚合对象的多种遍历。
为遍历不同的聚合结构提供一个统一的接口( 即, 支持多态迭代) 。
Definition : Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation.
Participants
The classes and/or objects participating in this pattern are:
Iterator (AbstractIterator)
defines an interface for accessing and traversing elements.
ConcreteIterator (Iterator)
implements the Iterator interface.
keeps track of the current position in the traversal of the aggregate.
Aggregate (AbstractCollection)
defines an interface for creating an Iterator object
ConcreteAggregate (Collection)
implements the Iterator creation interface to return an instance of the proper ConcreteIterator
Iterator 迭代模式,提供了一个访问 ConcreteAggregate 的方法。在软件构建过程中,集合对象内部结构常常变化各异。但对于这些集合对象,我们希望在不暴露其内部结构的同时,可以让外部客户代码透明地访问其中包含的元素;同时这种“透明遍历”也为同一种算法在多种集合对象上进行操作提供了可能。迭代抽象:访问一个聚合对象的内容而无需暴露它的内部表示。迭代多态:为遍历不同的集合结构提供一个统一的接口,从而支持同样的算法在不同的集合结构上进行操作。
Sample code in c#
This structural code demonstrates the Iterator pattern which provides for a way to traverse (iterate) over a collection of items without detailing the underlying structure of the collection.
// Iterator pattern -- Structural example
using System; using System.Collections; namespace DoFactory.GangOfFour.Iterator.Structural { // MainApp test application class MainApp { static void Main() { ConcreteAggregate a = new ConcreteAggregate(); a[0] = "Item A"; a[1] = "Item B"; a[2] = "Item C"; a[3] = "Item D"; // Create Iterator and provide aggregate ConcreteIterator i = new ConcreteIterator(a); Console.WriteLine("Iterating over collection:"); object item = i.First(); while (item != null ) { Console.WriteLine(item); item = i.Next(); } // Wait for user Console.Read(); } } // "Aggregate" abstract class Aggregate { public abstract Iterator CreateIterator(); } // "ConcreteAggregate" class ConcreteAggregate : Aggregate { private ArrayList items = new ArrayList(); public override Iterator CreateIterator() { return new ConcreteIterator(this ); } // Property public int Count { get { return items.Count; } } // Indexer public object this [int index] { get { return items[index]; } set { items.Insert(index, value ); } } } // "Iterator" abstract class Iterator { public abstract object First(); public abstract object Next(); public abstract bool IsDone(); public abstract object CurrentItem(); } // "ConcreteIterator" class ConcreteIterator : Iterator { private ConcreteAggregate aggregate; private int current = 0; // Constructor public ConcreteIterator(ConcreteAggregate aggregate) { this .aggregate = aggregate; } public override object First() { return aggregate[0]; } public override object Next() { object ret = null ; if (current < aggregate.Count - 1) { ret = aggregate[++current]; } return ret; } public override object CurrentItem() { return aggregate[current]; } public override bool IsDone() { return current >= aggregate.Count ? true : false ; } } }
Output
Iterating over collection:
Item A
Item B
Item C
Item D
This real-world code demonstrates the Iterator pattern which is used to iterate over a collection of items and skip a specific number of items each iteration.
// Iterator pattern -- Real World example
using System; using System.Collections; namespace DoFactory.GangOfFour.Iterator.RealWorld { // MainApp test application class MainApp { static void Main() { // Build a collection Collection collection = new Collection(); collection[0] = new Item("Item 0"); collection[1] = new Item("Item 1"); collection[2] = new Item("Item 2"); collection[3] = new Item("Item 3"); collection[4] = new Item("Item 4"); collection[5] = new Item("Item 5"); collection[6] = new Item("Item 6"); collection[7] = new Item("Item 7"); collection[8] = new Item("Item 8"); // Create iterator Iterator iterator = new Iterator(collection); // Skip every other item iterator.Step = 2; Console.WriteLine("Iterating over collection:"); for (Item item = iterator.First(); !iterator.IsDone; item = iterator.Next()) { Console.WriteLine(item.Name); } // Wait for user Console.Read(); } } class Item { string name; // Constructor public Item(string name) { this .name = name; } // Property public string Name { get { return name; } } } // "Aggregate" interface IAbstractCollection { Iterator CreateIterator(); } // "ConcreteAggregate" class Collection : IAbstractCollection { private ArrayList items = new ArrayList(); public Iterator CreateIterator() { return new Iterator(this ); } // Property public int Count { get { return items.Count; } } // Indexer public object this [int index] { get { return items[index]; } set { items.Add(value ); } } } // "Iterator" interface IAbstractIterator { Item First(); Item Next(); bool IsDone{ get ; } Item CurrentItem{ get ; } } // "ConcreteIterator" class Iterator : IAbstractIterator { private Collection collection; private int current = 0; private int step = 1; // Constructor public Iterator(Collection collection) { this .collection = collection; } public Item First() { current = 0; return collection[current] as Item; } public Item Next() { current += step; if (!IsDone) return collection[current] as Item; else return null ; } // Properties public int Step { get { return step; } set { step = value ; } } public Item CurrentItem { get { return collection[current] as Item; } } public bool IsDone { get { return current >= collection.Count ? true : false ; } } } }
Output
Iterating over collection:
Item 0
Item 2
Item 4
Item 6
Item 8