1.概述
Iterator(迭代器)模式用于提供一种方法使我们可以在不知道对象内部表示的情况下,按照一定顺序访问聚合对象中的各个元素。
2.UML图
3.角色
1)迭代器角色(Iterator):迭代器角色负责定义访问和遍历元素的接口。
2)具体迭代器角色(Concrete Iterator):具体迭代器角色要实现迭代器接口,并要记录遍历中的当前位置。
3)集合角色(Aggregate):集合角色负责提供创建具体迭代器角色的接口。
4)具体集合角色(Concrete Aggregate):具体集合角色实现创建具体迭代器角色的接口——这个具体迭代器角色于该集合的结构相关。
4.优缺点
优点:
1)将聚集的访问操作转移到迭代器中,简化了聚集的界面,这样就使得聚集只有组织其结构的操作。
2)由于迭代器的方法和聚集分离了,使迭代的算法可以独立于聚集而变化。
3)每个聚集对象都可以有一个或多个迭代子对象,每一个迭代子对象的迭代状态可以是彼此独立的。
缺点:
1)对于比较简单的遍历(像数组或者有序列表),使用迭代器方式遍历较为繁琐
5.适用性:
1)访问一个聚合对象的内容而无需暴露他的内部表示。
2)支持对聚合对象的多种遍历。
3)为遍历不同的聚合结构提供一个统一的接口(即, 支持多态迭代)。
6.代码
1)例一
1 #include "stdafx.h" 2 #include <iostream> 3 #include <string> 4 #include <vector> 5 6 class Iterator 7 { 8 public: 9 Iterator(){}; 10 virtual ~Iterator(){}; 11 virtual string First() = 0; 12 virtual string Next() = 0; 13 virtual string GetCur() = 0; 14 virtual bool IsEnd() = 0; 15 }; 16 17 class Aggregate 18 { 19 public: 20 virtual int Count() = 0; 21 virtual void Push(const string& strValue)=0; 22 virtual string Pop(const int nIndex)=0; 23 virtual Iterator* CreateIterator() = 0; 24 }; 25 26 class ConcreteIterator : public Iterator 27 { 28 public: 29 ConcreteIterator(Aggregate* pAggregate):m_nCurrent(0),Iterator() 30 { 31 m_Aggregate = pAggregate; 32 } 33 string First() 34 { 35 return m_Aggregate->Pop(0); 36 } 37 string Next() 38 { 39 string strRet; 40 m_nCurrent++; 41 if(m_nCurrent < m_Aggregate->Count()) 42 { 43 strRet = m_Aggregate->Pop(m_nCurrent); 44 } 45 return strRet; 46 } 47 string GetCur() 48 { 49 return m_Aggregate->Pop(m_nCurrent); 50 } 51 bool IsEnd() 52 { 53 return ((m_nCurrent >= m_Aggregate->Count()) ? true: false); 54 } 55 private: 56 Aggregate* m_Aggregate; 57 int m_nCurrent; 58 }; 59 60 class ConcreteAggregate : public Aggregate 61 { 62 public: 63 ConcreteAggregate():m_pIterator(NULL) 64 { 65 m_vecItems.clear(); 66 } 67 ~ConcreteAggregate() 68 { 69 if(NULL != m_pIterator) 70 { 71 delete m_pIterator; 72 m_pIterator = NULL; 73 } 74 } 75 Iterator* CreateIterator() 76 { 77 if(NULL == m_pIterator) 78 { 79 m_pIterator = new ConcreteIterator(this); 80 } 81 return m_pIterator; 82 } 83 int Count() 84 { 85 return m_vecItems.size(); 86 } 87 void Push(const string& strValue) 88 { 89 m_vecItems.push_back(strValue); 90 } 91 string Pop(const int nIndex) 92 { 93 string strRet; 94 if(nIndex < Count()) 95 { 96 strRet = m_vecItems[nIndex]; 97 } 98 return strRet; 99 } 100 private: 101 vector<string> m_vecItems; 102 Iterator* m_pIterator; 103 }; 104 105 int main() 106 { 107 ConcreteAggregate* pName = NULL; 108 pName = new ConcreteAggregate(); 109 if(NULL != pName) 110 { 111 pName->Push("hello"); 112 pName->Push("word"); 113 pName->Push("cxue"); 114 } 115 Iterator* iter = NULL; 116 iter = pName->CreateIterator(); 117 if(NULL != iter) 118 { 119 string strItem = iter->First(); 120 while(!iter->IsEnd()) 121 { 122 cout << iter->GetCur() << " is ok" << endl; 123 iter->Next(); 124 } 125 } 126 127 system("pause"); 128 return 0; 129 }
2)例二:添加模板类
#include "stdafx.h" #include <iostream> #include <string> #include <vector> class Iterator { public: Iterator(){}; virtual ~Iterator(){}; virtual string First() = 0; virtual string Next() = 0; virtual string GetCur() = 0; virtual bool IsEnd() = 0; }; class Aggregate { public: virtual int Count() = 0; virtual void Push(const string& strValue)=0; virtual string Pop(const int nIndex)=0; virtual Iterator* CreateIterator() = 0; }; class ConcreteIterator : public Iterator { public: ConcreteIterator(Aggregate* pAggregate):m_nCurrent(0),Iterator() { m_Aggregate = pAggregate; } string First() { return m_Aggregate->Pop(0); } string Next() { string strRet; m_nCurrent++; if(m_nCurrent < m_Aggregate->Count()) { strRet = m_Aggregate->Pop(m_nCurrent); } return strRet; } string GetCur() { return m_Aggregate->Pop(m_nCurrent); } bool IsEnd() { return ((m_nCurrent >= m_Aggregate->Count()) ? true: false); } private: Aggregate* m_Aggregate; int m_nCurrent; }; class ConcreteAggregate : public Aggregate { public: ConcreteAggregate():m_pIterator(NULL) { m_vecItems.clear(); } ~ConcreteAggregate() { if(NULL != m_pIterator) { delete m_pIterator; m_pIterator = NULL; } } Iterator* CreateIterator() { if(NULL == m_pIterator) { m_pIterator = new ConcreteIterator(this); } return m_pIterator; } int Count() { return m_vecItems.size(); } void Push(const string& strValue) { m_vecItems.push_back(strValue); } string Pop(const int nIndex) { string strRet; if(nIndex < Count()) { strRet = m_vecItems[nIndex]; } return strRet; } private: vector<string> m_vecItems; Iterator* m_pIterator; }; int main() { ConcreteAggregate* pName = NULL; pName = new ConcreteAggregate(); if(NULL != pName) { pName->Push("hello"); pName->Push("word"); pName->Push("cxue"); } Iterator* iter = NULL; iter = pName->CreateIterator(); if(NULL != iter) { string strItem = iter->First(); while(!iter->IsEnd()) { cout << iter->GetCur() << " is ok" << endl; iter->Next(); } } system("pause"); return 0; }