C++设计模式编程中的迭代器模式应用解析

时间:2021-08-17 04:21:58

迭代器模式:提供一种方法顺序访问一个聚合对象中个各个元素,而不暴露该对像的内部表示.

迭代器模式应该是最为熟悉的模式了,最简单的证明就是我在实现组合模式、享元模式、观察者模式中就直接用到了 STL 提供的迭代器来遍历 Vector 或者 List数据结构。

迭代器模式也正是用来解决对一个聚合对象的遍历问题,将对聚合的遍历封装到一个类中进行,这样就避免了暴露这个聚合对象的内部表示的可能。

模式的动机:
(1)一个聚合对象,如一个列表(List)或者一个集合(Set),应该提供一种方法来让别人可以访问它的元素,而又不需要暴露它的内部结构。
(2)针对不同的需要,可能还要以不同的方式遍历整个聚合对象,但是我们并不希望在聚合对象的抽象层接口中充斥着各种不同遍历的操作。
(3)怎样遍历一个聚合对象,又不需要了解聚合对象的内部结构,还能够提供多种不同的遍历方式,这就是迭代器模式所要解决的问题。

结构图:

C++设计模式编程中的迭代器模式应用解析

 

例子:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
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;
    }
  }
}

适用场景:

  • 访问一个聚合对象的内容而无需暴露它的内部表示。
  • 支持对聚合对象的多种遍历。
  • 为遍历不同的聚合结构提供一个统一的接口(即, 支持多态迭代)。