迭代器模式:提供一種方法順序訪問一個聚合對象中個各個元素,而不暴露該對像的內部表示.
迭代器模式應該是最為熟悉的模式了,最簡單的證明就是我在實現組合模式、享元模式、觀察者模式中就直接用到了 STL 提供的迭代器來遍歷 Vector 或者 List數據結構。
迭代器模式也正是用來解決對一個聚合對象的遍歷問題,將對聚合的遍歷封裝到一個類中進行,這樣就避免了暴露這個聚合對象的內部表示的可能。
模式的動機:
(1)一個聚合對象,如一個列表(List)或者一個集合(Set),應該提供一種方法來讓別人可以訪問它的元素,而又不需要暴露它的內部結構。
(2)針對不同的需要,可能還要以不同的方式遍歷整個聚合對象,但是我們并不希望在聚合對象的抽象層接口中充斥著各種不同遍歷的操作。
(3)怎樣遍歷一個聚合對象,又不需要了解聚合對象的內部結構,還能夠提供多種不同的遍歷方式,這就是迭代器模式所要解決的問題。
結構圖:
例子:
namespace Iterator_DesignPattern{ using System; using System.Collections; class Node { private string name; public string Name { get { return name; } } public Node(string s) { name = s; } } class NodeCollection { private ArrayList list = new ArrayList(); private int nodeMax = 0; // left as a student exercise - implement collection // functions to remove and edit entries also public void AddNode(Node n) { list.Add(n); nodeMax++; } public Node GetNode(int i) { return ((Node) list[i]); } public int NodeMax { get { return nodeMax; } } } /* * The iterator needs to understand how to traverse the collection * It can do that as way it pleases - forward, reverse, depth-first, */ abstract class Iterator { abstract public Node Next(); } class ReverseIterator : Iterator { private NodeCollection nodeCollection; private int currentIndex; public ReverseIterator (NodeCollection c) { nodeCollection = c; currentIndex = c.NodeMax -1; // array index starts at 0! } // note: as the code stands, if the collection changes, // the iterator needs to be restarted override public Node Next() { if (currentIndex == -1) return null; else return(nodeCollection.GetNode(currentIndex--)); } } /// <summary> /// Summary description for Client. /// </summary> public class Client { public static int Main(string[] args) { NodeCollection c = new NodeCollection(); c.AddNode(new Node("first")); c.AddNode(new Node("second")); c.AddNode(new Node("third")); // now use iterator to traverse this ReverseIterator i = new ReverseIterator(c); // the code below will work with any iterator type Node n; do { n = i.Next(); if (n != null) Console.WriteLine("{0}", n.Name); } while (n != null); return 0; } }}
適用場景:
- 訪問一個聚合對象的內容而無需暴露它的內部表示。
- 支持對聚合對象的多種遍歷。
- 為遍歷不同的聚合結構提供一個統一的接口(即, 支持多態迭代)。