设计模式之 - 迭代器模式
来源:互联网 发布:开淘宝需要什么 编辑:程序博客网 时间:2024/05/01 18:10
一、定义
迭代器( Iterator)模式,又叫做游标( Cursor)模式。 GOF 给出的定义为:提供一种方法访问一个容器( container)对象中各个元素,而又不需暴露该对象的内部细节。
从定义可见,迭代器模式是为容器而生。很明显,对容器对象的访问必然涉及到遍历算法。你可以一股脑的将遍历方法塞到容器对象中去;或者根本不去提供什么遍历算法,让使用容器的人自己去实现去吧。这两种情况好像都能够解决问题。然而在前一种情况,容器承受了过多的功能,它不仅要负责自己“容器”内的元素维护(添加、删除等等),而且还要提供遍历自身的接口;而且由于遍历状态保存的问题,不能对同一个容器对象同时进行多个遍历。第二种方式倒是省事,却又将容器的内部细节暴露无遗。而迭代器模式的出现,很好的解决了上面两种情况的弊端。
二、结构
先来看下迭代器模式的真面目吧:
1) 迭代器角色( Iterator):迭代器角色负责定义访问和遍历元素的接口。
2) 具体迭代器角色( ConcreteIterator):具体迭代器角色要实现迭代器接口,并要记录遍历中的当前位置。
3) 容器角色( Container):容器角色负责提供创建具体迭代器角色的接口。
4) 具体容器角色( Concrete Container):具体容器角色实现创建具体迭代器角色的接口——这个具体迭代器角色于该容器的结构相关。
三、实现
#include <iostream>using namespace std;//容器角色typedef struct tagNode{ int value; tagNode *pNext;}Node;//具体容器(用链表代替)class JTList{public: JTList() : m_pHead(NULL), m_pTail(NULL){}; JTList(const JTList &); ~JTList(); JTList &operator=(const JTList &); long GetCount() const; Node *Get(const long index) const; Node *First() const; Node *Last() const; bool Includes(const int &) const; void Append(const int &); void Remove(Node *pNode); void RemoveAll();private: Node *m_pHead; Node *m_pTail; long m_lCount;};//迭代器角色class Iterator{public: virtual void First() = 0; virtual void Next() = 0; virtual bool IsDone() const = 0; virtual Node *CurrentItem() const = 0;};JTList::~JTList(){ Node *pCurrent = m_pHead; Node *pNextNode = NULL; while (pCurrent) { pNextNode = pCurrent->pNext; delete pCurrent; pCurrent = pNextNode; }}long JTList::GetCount()const{ return m_lCount;}Node *JTList::Get(const long index) const{ // The min index is 0, max index is count - 1 if (index > m_lCount - 1 || index < 0) { return NULL; } int iPosTemp = 0; Node *pNodeTemp = m_pHead; while (pNodeTemp) { if (index == iPosTemp++) { return pNodeTemp; } pNodeTemp = pNodeTemp->pNext; } return NULL;}Node *JTList::First() const{ return m_pHead;}Node *JTList::Last() const{ return m_pTail;}bool JTList::Includes(const int &value) const{ Node *pNodeTemp = m_pHead; while (pNodeTemp) { if (value == pNodeTemp->value) { return true; } pNodeTemp = pNodeTemp->pNext; } return false;}void JTList::Append(const int &value){ // Create the new node Node *pInsertNode = new Node; pInsertNode->value = value; pInsertNode->pNext = NULL; // This list is empty if (m_pHead == NULL) { m_pHead = m_pTail = pInsertNode; } else { m_pTail->pNext = pInsertNode; m_pTail = pInsertNode; } ++m_lCount;}void JTList::Remove(Node *pNode){ if (pNode == NULL || m_pHead == NULL || m_pTail == NULL) { return; } if (pNode == m_pHead) // If the deleting node is head node { Node *pNewHead = m_pHead->pNext; m_pHead = pNewHead; } else { // To get the deleting node's previous node Node *pPreviousNode = NULL; Node *pCurrentNode = m_pHead; while (pCurrentNode) { pPreviousNode = pCurrentNode; pCurrentNode = pCurrentNode->pNext; if (pCurrentNode == pNode) { break; } } // To get the deleting node's next node Node *pNextNode = pNode->pNext; // If pNextNode is NULL, it means the deleting node is the tail node, we should change the m_pTail pointer if (pNextNode == NULL) { m_pTail = pPreviousNode; } // Relink the list pPreviousNode->pNext = pNextNode; } // Delete the node delete pNode; pNode = NULL; --m_lCount;}void JTList::RemoveAll(){ delete this;}//具体迭代器角色class JTListIterator : public Iterator{public: JTListIterator(JTList *pList) : m_pJTList(pList), m_pCurrent(NULL){} virtual void First(); virtual void Next(); virtual bool IsDone() const; virtual Node *CurrentItem() const;private: JTList *m_pJTList; Node *m_pCurrent;};void JTListIterator::First(){ m_pCurrent = m_pJTList->First();}void JTListIterator::Next(){ m_pCurrent = m_pCurrent->pNext;}bool JTListIterator::IsDone() const{ return m_pCurrent == m_pJTList->Last()->pNext;}Node *JTListIterator::CurrentItem() const{ return m_pCurrent;}int main(){ JTList *pJTList = new JTList; pJTList->Append(10); pJTList->Append(20); pJTList->Append(30); pJTList->Append(40); pJTList->Append(50); pJTList->Append(60); pJTList->Append(70); pJTList->Append(80); pJTList->Append(90); pJTList->Append(100); Iterator *pIterator = new JTListIterator(pJTList); // Print the list by JTListIterator for (pIterator->First(); !pIterator->IsDone(); pIterator->Next()) { cout<<pIterator->CurrentItem()->value<<"->"; } cout<<"NULL"<<endl; // Test for removing Node *pDeleteNode = NULL; for (pIterator->First(); !pIterator->IsDone(); pIterator->Next()) { pDeleteNode = pIterator->CurrentItem(); if (pDeleteNode->value == 100) { pJTList->Remove(pDeleteNode); break; } } // Print the list by JTListIterator for (pIterator->First(); !pIterator->IsDone(); pIterator->Next()) { cout<<pIterator->CurrentItem()->value<<"->"; } cout<<"NULL"<<endl; delete pIterator; delete pJTList; return 0;}
四、 适用情况
由上面的讲述,我们可以看出迭代器模式给容器的应用带来以下好处:1) 支持以不同的方式遍历一个容器角色。根据实现方式的不同,效果上会有差别。
2) 简化了容器的接口。
3) 对同一个容器对象,可以同时进行多个遍历。因为遍历状态是保存在每一个迭代器对象中的。
由此也能得出迭代器模式的适用范围:
1) 访问一个容器对象的内容而无需暴露它的内部表示。
2) 支持对容器对象的多种遍历。
3) 为遍历不同的容器结构提供一个统一的接口(多态迭代)。
0 0
- 设计模式之迭代器模式
- 设计模式之 迭代器模式
- 设计模式之迭代器模式
- 设计模式之迭代器模式
- 设计模式之--迭代器模式
- 设计模式之迭代器模式
- 设计模式之迭代器模式
- 设计模式之迭代器模式
- 设计模式之-迭代器模式
- 设计模式之迭代器模式
- 设计模式之迭代器模式
- 设计模式之迭代器模式
- 设计模式之迭代器模式
- 设计模式之迭代器模式
- 设计模式 之 迭代器模式
- 设计模式 之 迭代器模式
- 设计模式之迭代器模式
- 设计模式之迭代器模式
- Android 动画(四)---逐帧动画
- X Window 简单入门教程
- android new Handler().postDelayed() 延迟intent跳转
- HDU-1039-Easier Done Than Said?(Java && 没用正则表达式是我的遗憾.....)
- 【CF549B】Looksery Party
- 设计模式之 - 迭代器模式
- 国家与个人——国家决策的指导性
- leetcode--Jump Game
- 普通定时器应用
- 从GetSet看iOS内存机制 - 1
- 使用VS2010创建WebService 发布、测试
- nginx 安装配置 for window
- JavaWeb学习总结(五十)——文件上传和下载
- eclipse快捷键设置问题