c++/qt设计模式-迭代器模式

文章中部分内容和思路来自《Head First设计模式》


模式定义

提供一种方法顺序访问一个聚合对象中各个元素,而又不暴露其内部表示


模式类图

c++/qt设计模式-迭代器模式


典型案例

1.案例说明

中国象棋棋盘上有32颗棋子,提供一种对32颗棋子顺序遍历的方式


2.代码实现

-------------

IChessBoard.h

-------------

#ifndef ICHESSBOARD_H
#define ICHESSBOARD_H

#include "IIterator.h"

class IChessBoard
{
public:
    virtual IIterator *createIterator() = 0;
};

#endif // ICHESSBOARD_H


 

-----------

IIterator.h

-----------

#ifndef IITERATOR_H
#define IITERATOR_H

#include <QObject>

class IIterator
{
public:
    virtual bool hasNext() = 0;
    virtual QObject *next() = 0;
};

#endif // IITERATOR_H

 

-------------------

ChineseChessBoard.h

-------------------

#ifndef CHINESECHESSBOARD_H
#define CHINESECHESSBOARD_H

#include <QVector>

#include "IChessBoard.h"
#include "ChessMan.h"

class ChineseChessBoard : public IChessBoard
{
public:
    ChineseChessBoard();

public:
    void addChessMan(QString text, bool faceup);
    QVector<ChessMan *> getChessMen();
    virtual IIterator *createIterator();

private:
    QVector<ChessMan *> _chessManSet;
};

#endif // CHINESECHESSBOARD_H

 

---------------------

ChineseChessBoard.cpp

---------------------

#include "ChineseChessBoard.h"

#include "ChineseChessBoardIterator.h"

ChineseChessBoard::ChineseChessBoard()
{
    addChessMan("車", 1);
    addChessMan("馬", 1);
    addChessMan("炮", 1);
}

void ChineseChessBoard::addChessMan(QString text, bool faceup)
{
    ChessMan *man = new ChessMan(text, faceup);
    _chessManSet.append(man);
}

QVector<ChessMan *> ChineseChessBoard::getChessMen()
{
    return _chessManSet;
}

IIterator *ChineseChessBoard::createIterator()
{
    ChineseChessBoardIterator *it = new ChineseChessBoardIterator(_chessManSet);
    return it;
}

 

---------------------------

ChineseChessBoardIterator.h

---------------------------

#ifndef CHINESECHESSBOARDITERATOR_H
#define CHINESECHESSBOARDITERATOR_H

#include "ChessMan.h"
#include "IIterator.h"

#include <QVector>

class ChineseChessBoardIterator : public IIterator
{
public:
    ChineseChessBoardIterator(QVector<ChessMan *> chessManSet);

public:
    virtual bool hasNext();
    virtual QObject *next();

private:
    int _index;
    QVector<ChessMan *> _chessManSet;
};

#endif // CHINESECHESSBOARDITERATOR_H

 

-----------------------------

ChineseChessBoardIterator.cpp

-----------------------------

#include "ChineseChessBoardIterator.h"

ChineseChessBoardIterator::ChineseChessBoardIterator(QVector<ChessMan *> chessManSet)
{
    _index = 0;
    _chessManSet = chessManSet;
}

bool ChineseChessBoardIterator::hasNext()
{
    if (_chessManSet.length() <= _index)
        return false;

    return true;
}

QObject *ChineseChessBoardIterator::next()
{
    if (_chessManSet.length() <= _index)
        return NULL;

    ChessMan *man = (ChessMan *)_chessManSet[_index];
    ++_index;
    return man;
}

 

--------------------

ReversalChessBoard.h

--------------------

#ifndef REVERSALCHESSBOARD_H
#define REVERSALCHESSBOARD_H

#include <QVector>

#include "IChessBoard.h"
#include "ChessMan.h"

class ReversalChessBoard : public IChessBoard
{
public:
    ReversalChessBoard();

public:
    void addChessMan(QString text, bool faceup);
    QVector<ChessMan *> getChessMen();
    virtual IIterator *createIterator();

private:
    QVector<ChessMan *> _chessManSet;
};

#endif // REVERSALCHESSBOARD_H

 

----------------------

ReversalChessBoard.cpp

----------------------

#include "ReversalChessBoard.h"

#include "ReversalChessBoardIterator.h"

ReversalChessBoard::ReversalChessBoard()
{
    addChessMan("車", 0);
    addChessMan("馬", 0);
    addChessMan("炮", 0);
}

void ReversalChessBoard::addChessMan(QString text, bool faceup)
{
    ChessMan *man = new ChessMan(text, faceup);
    _chessManSet.append(man);
}

QVector<ChessMan *> ReversalChessBoard::getChessMen()
{
    return _chessManSet;
}

IIterator *ReversalChessBoard::createIterator()
{
    ReversalChessBoardIterator *it = new ReversalChessBoardIterator(_chessManSet);
    return it;
}

 

----------------------------

ReversalChessBoardIterator.h

----------------------------

#ifndef REVERSALCHESSBOARDITERATOR_H
#define REVERSALCHESSBOARDITERATOR_H

#include "ChessMan.h"
#include "IIterator.h"

#include <QVector>

class ReversalChessBoardIterator : public IIterator
{
public:
    ReversalChessBoardIterator(QVector<ChessMan *> chessManSet);

public:
    virtual bool hasNext();
    virtual QObject *next();

private:
    int _index;
    QVector<ChessMan *> _chessManSet;
};

#endif // REVERSALCHESSBOARDITERATOR_H

 

------------------------------

ReversalChessBoardIterator.cpp

------------------------------

#include "ReversalChessBoardIterator.h"

ReversalChessBoardIterator::ReversalChessBoardIterator(QVector<ChessMan *> chessManSet)
{
    _index = 0;
    _chessManSet = chessManSet;
}

bool ReversalChessBoardIterator::hasNext()
{
    if (_chessManSet.length() <= _index)
        return false;

    return true;
}

QObject *ReversalChessBoardIterator::next()
{
    if (_chessManSet.length() <= _index)
        return NULL;

    ChessMan *man = (ChessMan *)_chessManSet[_index];
    ++_index;
    return man;
}

 

----------

ChessMan.h

----------

#ifndef CHESSMAN_H
#define CHESSMAN_H

#include <QString>
#include <QObject>

class ChessMan : public QObject
{
public:
    ChessMan(QString text, bool faceup, QObject *parent = 0);

public:
    QString getText() const;
    bool getFaceup() const;

private:
    /** 只做实例,实际不止两个属性 **/
    QString _text; // 文本
    bool _faceup; // 正面向上
};

#endif // CHESSMAN_H

 

------------

ChessMan.cpp

------------

#include "ChessMan.h"

ChessMan::ChessMan(QString text, bool faceup, QObject *parent)
    : QObject(parent)
{
    _text = text;
    _faceup = faceup;
}

QString ChessMan::getText() const
{
    return _text;
}

bool ChessMan::getFaceup() const
{
    return _faceup;
}

 

--------

main.cpp

--------

/**
 * 设计模式-迭代器模式
 * 要点:1,迭代器角色 2,具体迭代器角色 3,容器角色 4,具体容器角色
 * 注意:边界处理
 */
#include <QCoreApplication>

#include <QDebug>

#include "ChineseChessBoard.h"
#include "ReversalChessBoard.h"
#include "ChineseChessBoardIterator.h"
#include "ReversalChessBoardIterator.h"

void printBoardChessMen(IIterator *it)
{
    int cont = 0;
    while (it->hasNext() && cont < 100)
    {
        ChessMan *man = (ChessMan *)it->next();
        qDebug() << man->getText() << " | 状态:" << man->getFaceup();

        cont++;
    }
}

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

    ChineseChessBoard cboard;
    IIterator *pcboard = cboard.createIterator();
    printBoardChessMen(pcboard);

    qDebug() << "--------------------------------";

    ReversalChessBoard rboard;
    IIterator *pboard = rboard.createIterator();
    printBoardChessMen(pboard);

    return a.exec();
}