简单易懂23种设计模式——迭代器模式【含C++代码实例】

23种设计模式C++实现——迭代器模式

   在做面向对象的软件开发时我们往往想达到更高的代码可复用性和更合理的软件颗粒度。
  根据《设计模式——可复用面向对象软件的基础》所说:“你必须找到相关的对象,以适当的颗粒度将他们回归类,再定义类的接口和继承层次,建立对象之间的基本关系。你的设计应该对手头的问题有针对性,同时对将来的问题和需求也要有足够的通用性。12
  内行的设计者知道:不是解决任何问题都要从头做起。他们更愿意复用以前使用的解决方案。这些重复的模式方案解决特定的问题,使得面向对象的设计更灵活、优雅,最终复用性更好。它们帮助设计者将新的设计建立在以往的工作基础上,复用以往的成功设计方案。一个熟悉这些设计模式的设计者不需要再去发现它们,而能够立即将他们应用于设计问题中。
  本系列文章主要参考文献为——设计模式,可复用面向对象软件的基础(Design Patterns Elements of Reusable Object-Oriented SoftWare Erich.),内部代码基本用C++语言编写。
  汇总链接:23种设计模式C++实现——概要(索引汇总)

摘要

本章主要说明迭代器模式,该设计模式主要意图是:提供一种方法顺序访问一个聚合对象中的各个元素,且不需要暴露该对象的内部表示。

主要参与者

该设计模式的参与者有5个,分别是:

  1. Iterator 抽象迭代器,定义访问和遍历的接口
  2. Aggregate 抽象聚合,定义创建相应迭代器对象的接口
  3. ConcreteAggregate 具体聚合,实现创建相应迭代器对象,保存聚合数据
  4. ConcreteIterator 具体迭代器,实现迭代器接口
  5. Client 用户

优点

  1. 访问一个聚合对象内部而无需暴露它的内部表示。
  2. 支持对聚合对象的多种遍历;
  3. 为遍历不同的聚合结构提供统一接口;

具体实现代码

这里实现一个简单迭代器遍历的例子,我们有一个ConcreteAggregate对象用来保存数据,新建一个针对其的迭代器用来遍历所有数据:

具体代码如下。

抽象迭代器(Iterator )

声明:

/****************************************************************
 Doc    :   iterator.h
 Author :   BingLee
 Date   :   2020-9-15
 Info   :   Iterator Design Patten
 https://blog.csdn.net/Bing_Lee (C)All rights reserved.
******************************************************************/
#ifndef ITERATOR_H
#define ITERATOR_H

#include <vector>

using namespace std;

template<class Item>
class Iterator
{
public:
    Iterator(){}
    virtual ~Iterator(){}
    virtual void first() = 0;
    virtual void next() = 0;
    virtual Item *currentItem() = 0;
    virtual bool isDone() = 0;
};

抽象聚合(Aggregate)

声明:

template<class Item>
class Aggregate
{
public:
    Aggregate(){}
    virtual ~Aggregate(){}
    virtual int getSize() = 0;
    virtual void push(Item item) = 0;
    virtual Item *at(const int nIndex) = 0;
    virtual Iterator<Item> *createIterator() = 0;
};

具体聚合(ConcreteAggregate)

声明:

template<class Item>
class ConcreteIterator;

template <class Item>
class ConcreteAggregate : public Aggregate<Item>
{
public:
    ConcreteAggregate(){}
    virtual ~ConcreteAggregate(){}

    virtual int getSize(){
        return m_data.size();
    }
    virtual void push(Item item){
        m_data.push_back(item);
    }
    virtual Item *at(const int nIndex){
        return &m_data[nIndex];
    }
    virtual Iterator<Item> *createIterator(){
        return new ConcreteIterator<Item>(this);
    }
private:
    vector<Item> m_data;
};

具体迭代器(ConcreteIterator )

声明:

template<class Item>
class ConcreteIterator : public Iterator <Item>
{
public:
    ConcreteIterator(Aggregate<Item> *aggregate): m_aggregate(aggregate), m_current(0){}
    virtual ~ConcreteIterator(){}

    virtual void first(){
        m_current = 0;
    }
    virtual void next(){
        if (m_current < m_aggregate->getSize())
        {
            ++m_current;
        }
    }
    virtual Item *currentItem(){
        if (m_current < m_aggregate->getSize())
        {
            return (m_aggregate->at(m_current));
        }
        else
        {
            return NULL;
        }
    }
    virtual bool isDone(){
        return m_current >= m_aggregate->getSize();
    }
private:
    Aggregate<Item> *m_aggregate;
    int m_current;
};

#endif // ITERATOR_H

用户(Client)

/****************************************************************
 Doc    :   main.cpp
 Author :   BingLee
 Date   :   2020-9-15
 Info   :   Iterator Design Patten
 https://blog.csdn.net/Bing_Lee (C)All rights reserved.
******************************************************************/

#include <QCoreApplication>
#include "iterator.h"

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

    printf("Templete is int.\n");
    Aggregate<int> *aggr = new ConcreteAggregate<int>;
    int num = 3;
    aggr->push(num--);
    aggr->push(num--);
    aggr->push(num--);
    Iterator<int> *iter = aggr->createIterator();
    for (iter->first(); !iter->isDone(); iter->next())
    {
        printf("Num is %d .\n", *(iter->currentItem()));
    }

    printf("Templete is float.\n");
    Aggregate<float> *aggr1 = new ConcreteAggregate<float>;
    float num1 = 9;
    aggr1->push(num1--);
    aggr1->push(num1--);
    aggr1->push(num1--);
    Iterator<float> *iter1 = aggr1->createIterator();
    for (iter1->first(); !iter1->isDone(); iter1->next())
    {
        printf("Num is %f .\n", *(iter1->currentItem()));
    }

    return a.exec();
}

输出结果:

在这里插入图片描述

补充说明

   通过上边这个简单的例子希望能说明什么是迭代器模式(Iterator),本篇在《设计模式——可复用面向对象软件的基础 》 的基础上实现了一种模板对象容器的迭代遍历,在client中有int和float聚合的遍历,如果需要专栏所有设计模式的源代码请留言留下你的联系方式,若能点赞、关注就更棒了!!!

本篇博客中的代码均已通过编译,如有Bug,请提出宝贵意见~

注:文章内函数可以把除Client对象的声明放在一个头文件中,实现放在一个文件中,Client文件放在主函数中执行。

参考:


  1. 《设计模式——可复用面向对象软件的基础 》 ↩︎

  2. Github design-patterns-for-humans ↩︎

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

机器人梦想家

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值