提供一种方法顺序访问一个聚合对象中各个元素, 而又不需暴露该对象的内部表示。
称 |
Iterator |
结构 |
![](/images/cnblogs_com/darkangel/Interpreter.gif) |
意图 |
提供一种方法顺序访问一个聚合对象中各个元素, 而又不需暴露该对象的内部表示。 |
适用性 |
- 访问一个聚合对象的内容而无需暴露它的内部表示。
- 支持对聚合对象的多种遍历。
- 为遍历不同的聚合结构提供一个统一的接口(即, 支持多态迭代)。
|
Code Example |
1 // Iterator 2![](/Images/OutliningIndicators/None.gif) 3 // Intent: "Provide a way to access the elements of an aggregate object 4 // sequentially without exposing its underlying representation". 5![](/Images/OutliningIndicators/None.gif) 6 // For further information, read "Design Patterns", p257, Gamma et al., 7 // Addison-Wesley, ISBN:0-201-63361-2 8![](/Images/OutliningIndicators/None.gif) 9![](/Images/OutliningIndicators/ExpandedBlockStart.gif) /**//* Notes: 10 * Here wish wish to separate node traversal from the nodes themselves. 11 * STL in ISO C++ is a highly successful application of this pattern. 12 * Generic programming is a great way to implement iterators. As this is 13 * not yet in C#, we use inheritance. 14 * 15 */ 16 17 namespace Iterator_DesignPattern 18![](/Images/OutliningIndicators/ExpandedBlockStart.gif) ![](/Images/OutliningIndicators/ContractedBlock.gif) { 19 using System; 20 using System.Collections; 21![](/Images/OutliningIndicators/InBlock.gif) 22 class Node 23![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) { 24 private string name; 25 public string Name 26![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) { 27 get 28![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) { 29 return name; 30 } 31 } 32 public Node(string s) 33![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) { 34 name = s; 35 } 36 } 37 38 class NodeCollection 39![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) { 40 private ArrayList list = new ArrayList(); 41 private int nodeMax = 0; 42 43 // left as a student exercise - implement collection 44 // functions to remove and edit entries also 45 public void AddNode(Node n) 46![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) { 47 list.Add(n); 48 nodeMax++; 49 } 50 public Node GetNode(int i) 51![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) { 52 return ((Node) list[i]); 53 } 54![](/Images/OutliningIndicators/InBlock.gif) 55 public int NodeMax 56![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) { 57 get 58![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) { 59 return nodeMax; 60 } 61 } 62 } 63![](/Images/OutliningIndicators/InBlock.gif) 64![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) /**//* 65 * The iterator needs to understand how to traverse the collection 66 * It can do that as way it pleases - forward, reverse, depth-first, 67 */ 68 abstract class Iterator 69![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) { 70 abstract public Node Next(); 71 } 72![](/Images/OutliningIndicators/InBlock.gif) 73 class ReverseIterator : Iterator 74![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) { 75 private NodeCollection nodeCollection; 76 private int currentIndex; 77![](/Images/OutliningIndicators/InBlock.gif) 78 public ReverseIterator (NodeCollection c) 79![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) { 80 nodeCollection = c; 81 currentIndex = c.NodeMax -1; // array index starts at 0! 82 } 83![](/Images/OutliningIndicators/InBlock.gif) 84 // note: as the code stands, if the collection changes, 85 // the iterator needs to be restarted 86 override public Node Next() 87![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) { 88 if (currentIndex == -1) 89 return null; 90 else 91 return(nodeCollection.GetNode(currentIndex--)); 92 } 93 } 94 95![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) /**//// <summary> 96 /// Summary description for Client. 97 /// </summary> 98 public class Client 99![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) { 100 public static int Main(string[] args) 101![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) { 102 NodeCollection c = new NodeCollection(); 103 c.AddNode(new Node("first")); 104 c.AddNode(new Node("second")); 105 c.AddNode(new Node("third")); 106![](/Images/OutliningIndicators/InBlock.gif) 107 // now use iterator to traverse this 108 ReverseIterator i = new ReverseIterator(c); 109![](/Images/OutliningIndicators/InBlock.gif) 110 // the code below will work with any iterator type 111 Node n; 112 do 113![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) { 114 n = i.Next(); 115 if (n != null) 116 Console.WriteLine("{0}", n.Name); 117 } while (n != null); 118 119 return 0; 120 } 121 } 122 } 123![](/Images/OutliningIndicators/None.gif) 124![](/Images/OutliningIndicators/None.gif) |