设计方式(c++)笔记之二十二(Iterator模式)

设计模式(c++)笔记之二十二(Iterator模式)

一、描述:


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


      Iterator 模式典型的结构图为: 


设计方式(c++)笔记之二十二(Iterator模式)

Iterator 模式中定义的对外接口可以视客户成员的便捷定义,但是基本的接口在图中的Iterator 中已经给出了(参考 STL 的 Iterator 就知道了)。 


二、实例


      周五下午,我正在看技术网站,第六感官发觉有人在身后,扭头一看,我 C,老大站在背后,赶忙站起来,“王经理,你找我?” 我说。
      “哦,在看技术呀。有个事情找你谈一下,你到我办公室来一下。” 老大说。到老大办公室,“是这样,刚刚我在看季报,我们每个项目的支出费用都很高,项目情况复杂,人员情况也不简单,我看着也有点糊涂,你看,这是我们现在还在开发或者维护的 103 个项目,你能不能先把这些项目信息重新打印一份给我,咱们好查查到底有什么问题。”

老大说。“这个好办,我马上去办”我爽快的答复道。 很快我设计了一个类图,并开始实施:


设计方式(c++)笔记之二十二(Iterator模式)



      老大一看,非常 Happy,这么快就出结果了,大大的把我夸奖了一番,然后就去埋头去研究那堆枯燥的报表了,然后我回到座位上,又看了一遍程序(心里很乐,就又想看看自己的成果),想想了,应该还有另外一种实现方式,因为是遍历嘛,让我想到的就是迭代器模式,我先把类图画出来: 


设计方式(c++)笔记之二十二(Iterator模式)


main(),客户

IProject,产品接口

CProject,产品类

IIterator,迭代器接口

IProjectIterator,产品迭代器接口

CProjectIterator,产品迭代器实现类

Convert,整型转字符型

说明:CProject实现产品类,能够返回一个迭代器的指针。这个迭代器将封装产品类里的一个数组。所以迭代器在运行Next函数时,可以遍历这个数组的所有元素。

简单来说,就是用代码实现vector<int>::iterator或vector<int>::const_iterator。


我的工程目录:


            设计方式(c++)笔记之二十二(Iterator模式)



代码:

迭代器接口:IIterator类

IIterator.h

#ifndef __Iterator__IIterator__
#define __Iterator__IIterator__

#include <iostream>
#include "IProject.h"
class IProject;
class IIterator
{
public:
    IIterator(void)
    {
    }
    virtual ~IIterator(void)
    {
    }
    virtual bool HasNext() = 0;
    virtual IProject * Next() = 0;
};

#endif /* defined(__Iterator__IIterator__) */

产品迭代器接口:IProjectIterator类

IProjectIterator.h

#ifndef __Iterator__IProjectIterator__
#define __Iterator__IProjectIterator__

#include <iostream>
#include "IIterator.h"
class IProject;


class IProjectIterator:public IIterator
{
public:
    IProjectIterator(void)
    {
    }
    virtual ~IProjectIterator(void)
    {
    }
    virtual bool HasNext() = 0;
    virtual IProject * Next() = 0;
};

#endif /* defined(__Iterator__IProjectIterator__) */

产品迭代器实现类:CProjectIterator类

CProjectIterator.h

#ifndef __Iterator__ProjectIterator__
#define __Iterator__ProjectIterator__

#include <iostream>
#include "IProjectIterator.h"
#include "IProject.h"
#include <vector>
using std::vector;

class CProjectIterator:public IProjectIterator
{
public:
    //构造函数传入projectList
    CProjectIterator(vector<IProject *> pl);
    ~CProjectIterator(void);
    
    //判断是否还有元素,必须实现
    bool HasNext();
    
    //取得下一个值
    IProject * Next();
    
private:
    vector<IProject *> m_projectList;      //所有的项目都放在这里vector中
    size_t m_currentItem;
    
};


#endif /* defined(__Iterator__ProjectIterator__) */
CProjectIterator.cpp

#include "ProjectIterator.h"

CProjectIterator::CProjectIterator(vector<IProject *> pl) : m_projectList(pl)
{
    m_currentItem = 0;
}
CProjectIterator::~CProjectIterator(void)
{
}
bool CProjectIterator::HasNext()
{
    bool b = true;
    if (m_currentItem >= m_projectList.size())
        b = false;
    return b;
}
IProject * CProjectIterator::Next()
{
    IProject *pp = m_projectList.at(m_currentItem ++);
    return pp;
}

产品接口:IProject类

IProject.h

#ifndef __Iterator__IProject__
#define __Iterator__IProject__

#include <iostream>
#include "IProjectIterator.h"
class IProjectIterator;

using std::string;
class IProject
{
public:
    IProject(void)
    {
    }
    virtual ~IProject(void)
    {
    }
    //增加项目
    virtual void Add(string name, int num, int cost) = 0;
    
    //从老板这里看到的就是项目信息
    virtual string GetProjectInfo() = 0;
    
    //获得一个可以被遍历的对象
    virtual IProjectIterator* GetIterator() = 0;
    virtual void Erase() = 0;
};

#endif /* defined(__Iterator__IProject__) */

产品类:CProject类

CProject.h

#ifndef __Iterator__Project__
#define __Iterator__Project__

#include <iostream>
#include "IProject.h"
#include "IProjectIterator.h"
#include "ProjectIterator.h"
#include <vector>
using std::string;
using std::vector;

class CProject :public IProject {
    
public:
    CProject(void);
    //定义一个构造函数,把所有老板需要看到的信息存储起来
    CProject(string name, int num, int cost);
    ~CProject(void);
    
    //得到项目的信息
    string GetProjectInfo();
    
    //增加项目
    void Add(string name, int num, int cost);
    
    //产生一个遍历对象
    IProjectIterator * GetIterator();
    
    //删除一个对象
    void Erase();
private:
    string m_name;                      //项目名称
    int m_num;                          //项目成员数量
    int m_cost;                         //项目费用
    vector<IProject*> m_projectList;    //定义一个项目列表,说有的项目都放在这里
};


#endif /* defined(__Iterator__Project__) */
CProject.cpp

#include "Project.h"
#include "Convert.h"

CProject::CProject( void )
{
    m_name = "";
    m_num = 0;
    m_cost = 0;
}
CProject::CProject(string name, int num, int cost) :m_name(name), m_num(num), m_cost(cost)
{
}
CProject::~CProject(void)
{
}
string CProject::GetProjectInfo()
{
    string info = "";
    info.append("项目名称是:");
    info.append(this->m_name);
    info.append("\t项目人数:");
    info.append(CConvert::ToString(m_num));
    info.append("\t项目费用:");
    info.append(CConvert::ToString(m_cost));
    return info;
}
void CProject::Add( string name, int num, int cost )
{
    this->m_projectList.push_back(new CProject(name, num, cost));
}
IProjectIterator * CProject::GetIterator()
{
    return new CProjectIterator(this->m_projectList);
}
void CProject::Erase()
{
    vector<IProject*>::reverse_iterator projectDelIt = m_projectList.rbegin();
    for (; projectDelIt != m_projectList.rend(); projectDelIt++)
    {
        delete (*projectDelIt);
        (*projectDelIt) = NULL;
    }
    m_projectList.clear();
}

整型转字符型:Convert类

Convert.h

#include <iostream>
using std::string;

#ifdef COMMONDECLARE_EXPORTS
#define COMMONDECLARE_API __declspec(dllexport)
#else
#define COMMONDECLARE_API __declspec(dllimport)
#endif

class COMMONDECLARE_API CConvert
{
public:
    CConvert(void);
    ~CConvert(void);
    static string ToString(int i);
};
Convert.cpp

#include "Convert.h"
#include <iostream>
#include <sstream>
using std::string;
using std::stringstream;


CConvert::CConvert(void)
{
}


CConvert::~CConvert(void)
{
}

string CConvert::ToString(int i)
{
    stringstream ss;
    ss << i;
    string result = ss.str();
    return result;
}

客户:main

main.cpp

#include <iostream>
#include "IProject.h"
#include "Project.h"
#include "Convert.h"
#include "ProjectIterator.h"
#include <vector>
using std::vector;
using std::cout;
using std::endl;

void DoIt()
{
    cout << "----------未使用迭代模式----------" << endl;
    vector<IProject*> projectList;
    
    projectList.push_back(new CProject("星球大战项目", 10, 100000));
    projectList.push_back(new CProject("扭转时空项目", 100, 10000000));
    projectList.push_back(new CProject("超人改造项目", 10000, 1000000000));
    
    for (int i = 4; i < 6; i ++)
    {
        string name = "";
        name.append("第");
        name.append(CConvert::ToString(i));
        name.append("个项目");
        projectList.push_back(new CProject(name, i * 5, i * 1000000));
    }
    
    vector<IProject*>::const_iterator projectIt = projectList.begin();
    for (; projectIt != projectList.end(); projectIt++)
        cout << (*projectIt)->GetProjectInfo().c_str() << endl;
    
    vector<IProject*>::reverse_iterator projectDelIt = projectList.rbegin();
    for (; projectDelIt != projectList.rend(); projectDelIt++)
    {
        delete (*projectDelIt);
        (*projectDelIt) = NULL;
    }
    projectList.clear();
}

void DoNew()
{
    cout << "----------使用迭代模式----------" << endl;
    IProject *pproject = new CProject();
    pproject->Add("星球大战项目", 10, 100000);
    pproject->Add("扭转时空项目", 100, 10000000);
    pproject->Add("超人改造项目", 10000, 1000000000);
    
    for (int i = 4; i < 6; i ++)
    {
        string name = "";
        name.append("第");
        name.append(CConvert::ToString(i));
        name.append("个项目");
        pproject->Add(name, i * 5, i * 1000000);
    }
    
    IProjectIterator *pprojectIt = pproject->GetIterator();
    while(pprojectIt->HasNext())
    {
        IProject *p = dynamic_cast<IProject*>(pprojectIt->Next());
        cout << p->GetProjectInfo().c_str() << endl;
    }
    delete pprojectIt;
    pprojectIt = NULL;
    pproject->Erase();
    delete pproject;
    pproject = NULL;
}


int main(int argc, const char * argv[])
{
    
    //使用Iterator模式之前
    DoIt();
    
    //使用Iterator
    DoNew();
    // insert code here...
    std::cout << "Hello, World!\n";
    return 0;
}

结果如下:


设计方式(c++)笔记之二十二(Iterator模式)


参考文献:《设计模式之禅》,《GoF_23种设计模式解析》

参考博客:  http://www.cnblogs.com/wanggary/archive/2011/04/19/2021600.html