迭代器模式(Iterator)- 設計模式(十四)

作用

提供一種方法順序訪問一個聚合對象中各個元素,而又不需暴露該對象的內部表示。簡單的來講,就是提供了一個索引,這個索引只能順序的訪問,並且不知道該對象的內部表示。比如我們經常用到的for循環語句,一般用作遍歷數組,其中的 ++i;其作用是每次循環之後i的值加1,這樣就能訪問下一個(下下一個)數組中的元素,也就是從頭至尾的遍歷了數組。將i抽象化後並使其能夠通用,則就形成了iterator模式。

迭代器模式是每個程序員無意之間接觸最早的設計模式,在STL編程中,每一種容器都有與之相關的自己的迭代器。

舉個例子

假設雞腿的包裝是線性的,每次買雞腿,售貨員都從最上面拿出來一個,以此類推,而你不知道這些雞腿包裝的具體結構,但是你通過售貨員又能夠知道這包雞腿裏面的所有雞腿的味道(當然需要花錢一個個買,要不然誰給你看)。售貨員可以看作是你訪問這些雞腿的一個迭代器。

優點

  • 它支持以不同的方式遍歷一個聚合對象。
  • 迭代器簡化了聚合類。
  • 在同一個聚合上可以有多個遍歷。
  • 在迭代器模式中,增加新的聚合類和迭代器類都很方便,無須修改原有代碼。
  • 職責分明,遍歷和存儲數據的職責分離。

缺點

由於迭代器模式將存儲數據和遍歷數據的職責分離,增加新的聚合類需要對應增加新的迭代器類,類的個數成對增加,這在一定程度上增加了系統的複雜性。

使用場景

  • 訪問一個聚合對象的內容而無須暴露它的內部表示。
  • 需要爲聚合對象提供多種遍歷方式。
  • 爲遍歷不同的聚合結構提供一個統一的接口。

注意事項

迭代器模式就是分離了集合對象的遍歷行爲,抽象出一個迭代器類來負責,這樣既可以做到不暴露集合的內部結構,又可讓外部代碼透明地訪問集合內部的數據。

UML 結構圖

在這裏插入圖片描述

例子

#include<iostream>
using namespace std;

template <typename T>
class ConcreateAggregate	//以簡單的List爲例說明下迭代器 
{
public:	
	ConcreateAggregate()
	{
	}

	virtual ~ConcreateAggregate()
	{
		delete[] m_pData;
		m_pData = NULL;
	}
	
	void setList(int nSize)
	{
		m_nSize = nSize;
		m_pData = new  T[nSize];
	}
	
	void append(const T& t)
	{
		static int nIndex = 0;
		m_pData[nIndex++] = t;
	}

	inline int size() const  { return m_nSize; }
	
	inline const T& at(int nIndex)
	{
		return (nIndex < m_nSize ? m_pData[nIndex] : T());
	}
	
	
	class Itreator : public ConcreateAggregate<T>
	{
		public:	
		
			Itreator(ConcreateAggregate* p) : m_pAggreate(p)
			{
				
			}
		
			virtual ~Itreator()
			{
				m_pAggreate = NULL;
				m_nIndex = 0; 
			}
			T value(int nIndex) const
			{
				return m_pAggreate->at(nIndex);
			}
			
			inline bool isDone()
			{
				return m_nIndex == m_pAggreate->size();
			}
			
			inline void next() 
			{
				m_nIndex < m_pAggreate->size() ? ++m_nIndex : m_nIndex; 
			}
			
			T current() const
			{
				return m_pAggreate->at(m_nIndex);
			}
			
		private:
			int m_nIndex{0};
			ConcreateAggregate* m_pAggreate{NULL};
	};
private:		
	int m_nSize{0};	
	T* m_pData;
};

int main(int argc, char* argv[])
{

#if 0
	ConcreateAggregate<int> pData;	//同樣的也可以以對象的形式創建 
	pData.setList(4);
#endif

	ConcreateAggregate<int>* pData = new ConcreateAggregate<int>();
	
	pData->setList(4);
	
	for(int nIndex = 0; nIndex < 4; ++nIndex)
	{
		pData->append(nIndex);
	}
	
	ConcreateAggregate<int>::Itreator* itor = new ConcreateAggregate<int>::Itreator(pData);
		
	cout << itor->value(1) << "	" << pData->at(2) << endl;
	
	for(; false == itor->isDone(); itor->next())
	{
		cout << itor->current() << " ..." << endl;
	}
		
	delete pData;
	pData = NULL;
	delete itor;
	itor = NULL;
	return 0;
}

運行結果

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章