可撤销的command pattern

#include "Publicinc.hpp"
// Receiver
class  Receiver
{
public:
    string GetContent() const { return m_content; }
    void   SetContent(const string& content) { m_content = content; }
    void   Append(const string& strAppend) { m_content.append(strAppend); }
//    void   Show() const { printf("content is {%s}\n", m_content.c_str()); }
private:
    string m_content;
};

ostream&  operator<< (ostream& os, const Receiver& rhs)
{
    os << "the current is: " << rhs.GetContent() << endl;
    return os;
}

// void  TestRecevier()
// {
//    Receiver  r;
//    r.SetContent("abc");
//    r.Show();


//    cout << r;
// }

class  Command
{
public:
    Command(Receiver* pReceiver, string strAppend)
        : m_pReceiver(pReceiver)
        , m_append(strAppend)
    {
    }

    virtual  ~Command() {}

    virtual  void  Execute() = 0;

protected:
    Receiver*  m_pReceiver;
    string  m_append;
};

class  UndoCommand : public Command
{
public:
    UndoCommand(Receiver* pReceiver, string strAppend)
        : Command(pReceiver, strAppend)
    {
    }

    virtual  void   Undo() = 0;
    virtual  void   Redo() = 0;
};

class  ConcreteCommand : public UndoCommand
{
public:
    ConcreteCommand(Receiver* pReceiver, string strAppend)
        : UndoCommand(pReceiver, strAppend)
    {
    }

    virtual  void  Execute()
    {
        m_prevContent = m_pReceiver->GetContent();
        m_pReceiver->Append(m_append);
        m_currContent = m_pReceiver->GetContent();
    }

    virtual  void   Undo()
    {
        m_pReceiver->SetContent(m_prevContent);
    }

    virtual  void   Redo()
    {
        m_pReceiver->SetContent(m_currContent);
    }

private:
    string  m_prevContent;
    string  m_currContent;
};

class  CommandManager
{
    typedef  std::stack<Command*>   CommandStack;
public:
    ~CommandManager()
    {
        while (m_exeCommands.size() > 0) {
            Command* command = m_exeCommands.top();
            m_exeCommands.pop();
            delete command;
        }

        while (m_undoCommands.size() > 0) {
            Command* command = m_undoCommands.top();
            m_undoCommands.pop();
            delete command;
        }
    }

    void  ExecuteCmd(Command* pCommand)
    {
        pCommand->Execute();
    }

    void  UndoCmd()
    {
        if (m_exeCommands.size() > 0) {
            UndoCommand* pCommand = dynamic_cast<UndoCommand*>(m_exeCommands.top());
            m_exeCommands.pop();
            pCommand->Undo();
            m_undoCommands.push(pCommand);
        }
    }

    void  RedoCmd()
    {
        if (m_undoCommands.size() > 0) {
            UndoCommand* pCommand = dynamic_cast<UndoCommand*>(m_undoCommands.top());
            m_undoCommands.pop();
            pCommand->Redo();
            m_exeCommands.push(pCommand);
        }
    }

private:
    CommandStack   m_exeCommands;
    CommandStack   m_undoCommands;
};

void  TestCommandUndoRedo()
{
    CommandManager  manager;
    Receiver  receiver;
  //  cout << r;

    manager.ExecuteCmd(new  ConcreteCommand(&receiver, "Zhongguo"));
    manager.ExecuteCmd(new  ConcreteCommand(&receiver, " "));
    manager.ExecuteCmd(new  ConcreteCommand(&receiver, "American"));
    manager.ExecuteCmd(new  ConcreteCommand(&receiver, " "));
    manager.ExecuteCmd(new  ConcreteCommand(&receiver, "Australia"));

    cout << receiver;

    manager.UndoCmd();

    cout << receiver;

    manager.UndoCmd();

    cout << receiver;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值