设计模式 c++版(13)——迭代器模式

定义:
它提供一种方法访问一个容器对象中各个元素,而又不暴露该对象的内部细节。


说明:
目前基本上没人会单独写一个迭代器,除非是产品性质的开发
迭代器是为容器服务的,能容纳对象的所有类型的都可以称之为容器,迭代器模式就是胃解决遍历这些容器中的元素而诞生的。
迭代器模式提供了遍历容器的方便性,容器只要管理增减元素就可以了,需要遍历时交由迭代器进行。

 

示例一:迭代器模式(通用版)

1. 类图20-3

 

2. 结构说明

  •  Iterator 抽象迭代器:抽象迭代器负责定义访问和遍历元素的接口,而且基本上是有固定的3个方法:first() 获得第一个元素, next() 访问下一个元素, isDone() 是否已经访问到底部
  •  ConcreteIterator 具体迭代器:具体迭代器角色要实现迭代器接口,完成容器元素的遍历。
  •  Aggregate 抽象容器:容器角色负责提供创建具体迭代器角色的接口,必然提供一个类似 createIterator() 这样的方法。
  •  Concrete Aggregate 具体容器:具体容器实现容器接口定义的方法,创建出容纳迭代器的对象。


3. 代码清单
 

    **********  3.迭代器模式(通用版),代码清单20-3:***************//

//抽象迭代器
class Interator
{
public:
    virtual QString   next()      = 0;
    virtual bool      hasNext()   = 0;
    virtual bool      remove()    = 0;
};

//具体迭代器
class ConcreteIterator:public Interator
{
public:
    ConcreteIterator()
        :m_list()
        ,m_cursor(0)
    {}
    ConcreteIterator(QList<QString> list)
        :m_list(list)
        ,m_cursor(0)
    {}
    virtual bool    hasNext()
    {
        bool result = false;
        if (this->m_cursor != this->m_list.size())
        {
            result = true;
        }
        return result;
    }
    virtual QString next()
    {
        QString object;
        if (this->hasNext())
        {
            object = this->m_list.at(m_cursor++);
        }
        return object;
    }
    virtual bool    remove()
    {
        this->m_list.removeAt(m_cursor++);
        return true;
    }
    
private:
    QList<QString>   m_list;
    int              m_cursor;
};

//抽象容器
class Aggregate
{
public:
    virtual void        add(QString object)     = 0;
    virtual void        remove(QString object)  = 0;
    virtual Interator*  iterator()              = 0;
};

//具体容器
class ConcreteAggregate:public Aggregate
{
public:
    ConcreteAggregate(){}
    virtual void        add(QString object)
    {
        this->m_list.push_back(object);
    }
    virtual void        remove(QString object)
    {
        this->m_list.removeOne(object);
    }
    
    virtual Interator*  iterator()
    {
        Interator* interactor = new ConcreteIterator(this->m_list);
        return interactor;
    }
    
private:
    QList<QString>   m_list;
};

int main()
{
    Aggregate *agg = new ConcreteAggregate();
    agg->add("abc");
    agg->add("aaa");
    agg->add("123");
    
    Interator *iter = agg->iterator();
    while(iter->hasNext())
    {
        qDebug() << iter->next();
    }
    
    return 0;
}



示例二:整理项目信息

1. 类图20-1

 

2..代码清单
 

//    **********  1.整理项目信息,代码清单20-1:***************//

//项目信息接口
class IProject
{
public:
    virtual QString getProjectInfo() = 0;
};

//项目信息实现
class Project:public IProject
{
public:
    Project(QString name, int num, int cost)
    {
        this->m_cost = cost;
        this->m_name = name;
        this->m_num  = num;
    }
    virtual QString  getProjectInfo() //这里用QString::number做了转化,否则在字符串拼接的时候输出会有错误
    {
        QString info;
        info = "project name: " + m_name
                + " people num: " + QString::number(m_num)
                + " project cost: " + QString::number(m_cost);
        return info;
    }

private:
    QString     m_name;     //项目名称
    int         m_num;      //项目成员数量
    int         m_cost;     //项目费用
};

int main ()
{
    QList<IProject*> projectList;
    IProject* pro1 = new Project("aaa", 10, 10000);
    IProject* pro2 = new Project("bbb", 20, 20000);
    IProject* pro3 = new Project("ccc", 30, 30000);
    
    projectList.push_back(pro1);
    projectList.push_back(pro2);
    projectList.push_back(pro3);
    
    QList<IProject*>::ConstIterator iter = projectList.begin();
    while(iter != projectList.end())
    {
        IProject* project = *iter;
        qDebug() << project->getProjectInfo();
                
        ++iter;
    }
    
    
    return 0;
}

 

示例三:整理项目信息(增加迭代器访问方式)

1. 类图20-2


2. 代码清单20-2
 

    **********  2.整理项目信息(增加迭代器访问方式),代码清单20-2:***************//

class ProjectIterator;

//项目信息接口
class IProject
{
public:
    virtual void                add(QString name, int num, int cost) = 0;
    virtual QString             getProjectInfo()                     = 0;
    virtual ProjectIterator*    iterator()                           = 0;
};

typedef QList<IProject*> ProjectList;

//迭代器接口
class Interator
{
public:
    virtual IProject*   first()      = 0;
    virtual IProject*   next()       = 0;
    virtual bool        hasNext()    = 0;
};

//迭代器实现
class ProjectIterator:public Interator
{
public:
    ProjectIterator()
        :m_list()
        ,m_current(0)
    {}
    ProjectIterator(ProjectList list)
        :m_list()
        ,m_current(0)
    {
        this->m_list = list;
    }
    virtual IProject* first()
    {
        IProject* project = this->m_list.first();
        return project;
    }
    virtual IProject* next()
    {
        IProject* project = nullptr;
        if (this->hasNext())
        {
            project = this->m_list.at(m_current++);
        }
        return project;
    }
    virtual bool    hasNext()
    {
        bool result = false;
        if (this->m_current != this->m_list.size())
        {
            result = true;
        }
        return result;
    }

private:
    ProjectList m_list;
    int         m_current;
};

//项目信息实现
class Project:public IProject
{
public:
    Project(){}
    virtual void        add(QString name, int num, int cost)
    {
        IProject *project = new Project(name, num, cost);
        this->m_list.push_back(project);
    }

    virtual QString  getProjectInfo() //这里用QString::number做了转化,否则在字符串拼接的时候输出会有错误
    {
        QString info;
        info = "project name: " + m_name
                + " people num: " + QString::number(m_num)
                + " project cost: " + QString::number(m_cost);
        return info;
    }
    virtual ProjectIterator* iterator()
    {
        ProjectIterator* proIter =  new ProjectIterator(this->m_list);
        return proIter;
    }
   
private:
    Project(QString name, int num, int cost)
    {
        this->m_cost = cost;
        this->m_name = name;
        this->m_num  = num;
    }

private:
    QString          m_name;     //项目名称
    int              m_num;      //项目成员数量
    int              m_cost;     //项目费用
    ProjectList      m_list;     //项目列表
};

int main ()
{
    IProject* pro = new Project();
    pro->add("aaa", 10, 10000);
    pro->add("bbb", 20, 20000);
    pro->add("ccc", 30, 30000);
    
    ProjectIterator *proIter = pro->iterator();
    
    while(proIter->hasNext())
    {
        qDebug() << proIter->next()->getProjectInfo();
    }
    
    return 0;
}


三、迭代器模式的应用

  • 我们在例子中使用了迭代器模式后原本简单的应用编的复杂了,是因为我们在简单的应用中使用了迭代器。它为什么能够运行起来呢,是因为QList已经实现了iterator()方法,我们才可以简单地应用。
  • 现在基本所有的高级语言都有迭代器的接口或实现,我们再去写迭代器,就有点多余了。所以迭代器模式有点没落了,基本上很少有项目再独立写迭代器了,直接使用已提供的就可以完美地解决问题了。
  • 迭代器现在应用得越来越广泛了,甚至已经成为一个最基础的工具。

 


参考文献《秦小波. 设计模式之禅》(第2版) (华章原创精品) 机械工业出版社

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值