我的应用程序是使用 Qt 在 C++ 中开发的,并且正在使用信号和插槽。
假设我有以下类(伪 C++ 代码):
class Ball
{
Color m_Color;
int m_Size;
};
class Player
{
public:
setBall(Ball* pBall)
{
if (pBall != m_pBall)
{
Ball* pPreviousBall = m_pBall;
m_pBall = pBall;
emit notifyBallNotUsed(pPreviousBall);
}
}
Ball* getBall();
signals:
void notifyBallNotUsed(Ball*);
private:
String m_Name;
Ball* m_pBall;
};
class GeneralHandler
{
public:
addBall(Ball* pBall);
deleteBall(Ball* pBall);
addPlayer(Player* pPlayer)
{
connect(pPlayer, SIGNAL(notifyBallNotUsed(Ball*)), this, SLOT(onBallUsageChanged(Ball*)));
...
}
deletePlayer(Player* pPlayer);
{
disconnect(pPlayer, SIGNAL(notifyBallNotUsed(Ball*)), this, SLOT(onBallUsageChanged(Ball*)));
onBallUsageChanged(pPlayer->getBall());
....
}
private slots:
void onBallUsageChanged(Ball* pBall)
{
if (isNotUsedAnymore(pBall))
{
m_BallList.remove(pBall);
delete pBall;
}
}
private:
bool isNotUsedAnymore(Ball* pBall); // Check if the given ball is still used by at least one player
List<Player*> m_PlayerList;
List<Ball*> m_BallList;
};
使用我的应用程序,用户可以添加/删除球员,并为每个球员决定球的颜色和大小。在引擎盖后面,GeneralHandler 负责存储球并删除它们。两名球员使用同一个球是完全可能的。
当一个球员被删除时,如果球不再被使用,GeneralHandler 应该删除它(如果球仍然被另一个球员使用,则保留它)。如果球员正在使用的球被改变,前一个球,如果不再使用,也应该被 GeneralHandler 删除。
到现在为止还挺好。
现在,我想使用命令模式向我的应用程序添加撤消/重做功能,这就是我卡住的地方。可以说我有这样的事情:
class ChangePlayerBall : public QUndoCommand
{
public:
ChangePlayerBall(Player* pPlayer, Ball* pNewBall)
{
m_pPlayer = pPlayer;
}
void redo();
void undo();
private:
Player* m_pPlayer;
};
我猜 redo() 方法看起来像这样:
void ChangePlayerBall::redo()
{
m_pPlayer->setBall(pNewBall);
}
如果上面的代码中没有任何其他更改,那么如果其他玩家不再使用之前的 Ball 将被删除。这在实现 undo() 方法时会出现问题:如果前一个球已被删除,我不知道它的特征是什么,并且 undo 命令将无法重新创建它。或者也许我应该存储前一个球,但是撤消/重做命令如何知道这个前一个球是否仍然存在或已被处理程序删除?或者也许应该在撤消命令中实现这种一旦不再使用就删除球的机制?问题是 undo 命令会对许多其他类有很多依赖。另一个问题是此代码将在 DeletePlayer 命令中部分重复,这将不得不执行类似的操作:
class DeletePlayer : public QUndoCommand
{
public:
DeletePlayer(Player* pPlayer);
void redo();
void undo();
...
};
我希望我的解释可以理解!
你将如何解决这个问题?我找不到令人满意的解决方案。
谢谢 !