Design pattern-iterator pattern (the basic principles and ideas of iterator implementation)

Iterator pattern: Provides a way to sequentially access each element in an aggregate object without exposing the internal table representation of the object

The iterator mode is to provide a unified interface for traversing different aggregation structures such as start, next, end or not, which item is currently, etc.

Here is an example of letting passengers buy tickets on a bus:

#ifndef ITERATOR_H
#define ITERATOR_H

#include <QSharedPointer>
#include <QList>
class Aggregate;
class Iterator   //Iterator迭代器抽象类
{
public:
    virtual QString First() = 0;
    virtual QString Next() = 0;
    virtual bool IsDone() = 0;
    virtual QString CurrentItem() = 0;
    virtual ~Iterator(){}
};

class Aggregate   //Aggregate聚集抽象类
{
public:
    virtual Iterator* CreateIterator() = 0;
    virtual ~Aggregate(){}
};

class ConcreteAggregate;
class ConcreteIterator final: public Iterator
{
public:
    ConcreteIterator(ConcreteAggregate * a);
    QString First() override ;
    QString Next() override ;
    bool IsDone() override;
    QString CurrentItem() override;
private:
    QSharedPointer<ConcreteAggregate> _aggregate;
    int _current = 0;
};

class ConcreteAggregate final : public Aggregate
{
public:
    Iterator * CreateIterator() override {return new ConcreteIterator(this);}
    int Count() {return _items.count();}
    QString& operator[](int i) {return _items[i];}
    void set(QString s){_items.append(s);}
private:
    QList<QString> _items;
};

#endif // ITERATOR_H

Because the forward declaration is used in the header file, it is necessary to implement pointer-related operations in the source file.

#include "iterator.h"

ConcreteIterator::ConcreteIterator(ConcreteAggregate *a)
{
    _aggregate = QSharedPointer<ConcreteAggregate>(a);
}

QString ConcreteIterator::First()
{
    return (*_aggregate)[0];
}

QString ConcreteIterator::Next()
{
    _current++;
    if(_current<_aggregate->Count())
        return (*_aggregate)[_current];
    return nullptr;
}

bool ConcreteIterator::IsDone()
{
    return _current >= _aggregate->Count() ? true : false;
}

QString ConcreteIterator::CurrentItem()
{
    return (*_aggregate)[_current];
}

Finally, add passengers to the main function, and then iteratively print the results:

#include "iterator.h"

#include <QDebug>

int main(int argc,char* argv[])
{
    ConcreteAggregate *a = new ConcreteAggregate();

    a->set("大鸟");
    a->set("小菜");
    a->set("行李");
    a->set("老外");
    a->set("公交内部员工");
    a->set("小偷");

    Iterator *i = new ConcreteIterator(a);
    QString item = i->First();
    while(!i->IsDone())
    {
        qDebug()<< i->CurrentItem();
        i->Next();
    }

    return 0;
}
  •  

In fact, general containers now support iterators to traverse various data. Implementing simple iterators here allows us to have a deeper understanding of the operating mechanism of iterators, so that we can use it more at ease~

Finally, put the source code address: https://github.com/Dongzhixiao/designMode_qt/tree/master/BuyTicket_Iterator_pattern_20

Guess you like

Origin blog.csdn.net/jiesunliu3215/article/details/108950169