c++/qt设计模式-迭代器模式
文章中部分内容和思路来自《Head First设计模式》
模式定义
提供一种方法顺序访问一个聚合对象中各个元素,而又不暴露其内部表示
模式类图
典型案例
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();
}