016 --- 第20章 迭代器模式


简述:

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

  迭代器模式包括:抽象聚集类、具体聚集类、抽象迭代类、具体迭代类。

    抽象聚集类:封装一个抽象迭代类对象。

    具体聚集类:继承自抽象聚集类。

    抽象迭代类:用于定义得到开始对象、得到下一个对象、判断是否到结尾、当前对象等抽象方法,统一接口。

    具体迭代类:继承自抽象迭代类,实现开始、下一个、是否结尾、当前对象等方法。

迭代器模式:

  1 #include 
  2 #include 
  3 using namespace std;
  4 
  5 class CObject
  6 {
  7 public:
  8     string m_szData;
  9 
 10 public:
 11     CObject(string szData) : m_szData(szData){}
 12 };
 13 
 14 // 抽象迭代器类
 15 class CIterator
 16 {
 17 public:
 18     virtual CObject* First() = 0;
 19     virtual CObject* Next() = 0;
 20     virtual bool IsDone() = 0;
 21     virtual CObject* CurrentItem() = 0;
 22 };
 23 
 24 // 抽象聚集类
 25 class CAggregate
 26 {
 27 public:
 28     virtual CIterator* CreateIterator(CIterator* pIterator) = 0;
 29 };
 30 
 31 // 具体聚集类
 32 class CConcreteAggregate : public CAggregate
 33 {
 34 private:
 35     list m_lstItems;
 36     CIterator* m_pIterator;
 37 
 38 public:
 39     virtual CIterator* CreateIterator(CIterator* pIterator)
 40     {
 41         m_pIterator = pIterator;
 42         return m_pIterator;
 43     }
 44 
 45     int Count() { return m_lstItems.size(); }
 46 
 47     CObject* operator[](int nIndex)
 48     {
 49         CObject* pObj = NULL;
 50         if (nIndex > m_lstItems.size() - 1)
 51             return pObj;
 52         
 53         list::iterator ite = m_lstItems.begin();
 54         int n = 0;
 55         while (ite != m_lstItems.end())
 56         {
 57             if (n == nIndex)
 58             {
 59                 pObj = (*ite);
 60                 break;
 61             }
 62 
 63             n++;
 64             ite++;
 65         }
 66 
 67         return pObj;
 68     }
 69 
 70     list& GetList() { return m_lstItems; }
 71 };
 72 
 73 // 具体迭代类
 74 class CConcreteIterator : public CIterator
 75 {
 76 private:
 77     CConcreteAggregate* m_pAggregate;
 78     int m_nCurrent;
 79 
 80 public:
 81     CConcreteIterator(CConcreteAggregate* pAggregate)
 82     {
 83         m_pAggregate = pAggregate;
 84         m_nCurrent = 0;
 85     }
 86 
 87     virtual CObject* First() { return (*m_pAggregate)[0]; }
 88 
 89     virtual CObject* Next()
 90     {
 91         CObject* pObject = NULL;
 92         m_nCurrent++;
 93         if (m_nCurrent < m_pAggregate->Count())
 94             pObject = (*m_pAggregate)[m_nCurrent];
 95         
 96         return pObject;
 97     }
 98 
 99     virtual bool IsDone() { return m_nCurrent >= m_pAggregate->Count() ? true : false; }
100 
101     virtual CObject* CurrentItem() { return (*m_pAggregate)[m_nCurrent]; }
102 };
103 
104 // 具体反向迭代类
105 class CConcreteIteratorDesc : CIterator
106 {
107 private:
108     CConcreteAggregate* m_pAggregate;
109     int m_nCurrent;
110 
111 public:
112     CConcreteIteratorDesc(CConcreteAggregate* pAggregate)
113     {
114         m_pAggregate = pAggregate;
115         m_nCurrent = m_pAggregate->Count() - 1;
116     }
117 
118     virtual CObject* First() { return (*m_pAggregate)[m_pAggregate->Count() - 1]; }
119 
120     virtual CObject* Next()
121     {
122         CObject* pObject = NULL;
123         m_nCurrent--;
124         if (m_nCurrent < m_pAggregate->Count())
125             pObject = (*m_pAggregate)[m_nCurrent];
126         
127         return pObject;
128     }
129 
130     virtual bool IsDone() { return m_nCurrent < 0 ? true : false; }
131 
132     virtual CObject* CurrentItem() { return (*m_pAggregate)[m_nCurrent]; }
133 };
134 
135 int main()
136 {
137     CConcreteAggregate Aggregate;
138     CObject obj("GGG"), obj1("HHH"), obj2("LLL");
139     Aggregate.GetList().push_back(&obj);
140     Aggregate.GetList().push_back(&obj1);
141     Aggregate.GetList().push_back(&obj2);
142 
143     //CConcreteIterator Iterator(&Aggregate);
144     CConcreteIteratorDesc Iterator(&Aggregate);
145     CObject* pObj = Iterator.First();
146     while (!Iterator.IsDone())
147     {
148         cout << Iterator.CurrentItem()->m_szData << " 请买车票!" << endl;
149         Iterator.Next();
150     }
151 
152     system("pause");
153     return 0;
154 }

输出结果: