把请求封装成一个对象,从而分离请求发起和执行。发起者和执行者之间通过命令对象进行沟通,便于请求对象的储存、传递、调用、增加和管理。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 class Command { protected : Application* app_; Editor* editor_; std::string backup_; public : Command (Application* app, Editor* editor): app_ (app), editor_ (editor) {} void saveBackup () { backup_ = editor_->text; } void undo () { editor_->setText (backup_); } virtual bool execute () = 0 ; }; class CopyCommand : public Command { bool execute () override { app_->setClipboard (editor_->getSelection ()); return true ; } }; class CutCommand : public Command { bool execute () override { saveBackup (); app_->setClipboard (editor_->getSelection ()); editor_->deleteSelection (); return true ; } }; class PasteCommand : public Command { bool execute () override { saveBackup (); editor_->replaceSelection (app->getClipboard ()); return true ; } }; class UndoCommand : public Command { bool execute () override { app_->undo (); return false ; } }; class CommandHistory { private : std::vector<Command*> history_; public : void push (Command* c) { history_.push_back (c); } Command* pop () { if (history_.empty ()) return nullptr ; Comman* cmd = history_.back (); history_.pop_back (); return cmd; } }; class Editor { public : std::string text_; std::string getSelection () { } void deleteSelection () { } void replaceSelection (std::string text) { } }; class Application { public : std::string clipboard_; std::vector<Editor*> editors_; Editor* activeEditor_; CommandHistory history; void createUI { std::function<void ()> copy = [this ]() { executeCommand (new CopyCommand (this , activeEditor_)); } copyButton.setCommand (copy); shortcuts.onKeyPress ("ctrl+c" , copy); std::function<void ()> cut = [this ]() { executeCommand (new CutCommand (this , activeEditor_)); } cutButton.setCommand (cut); shortcuts.onKeyPress ("ctrl+x" , cut); std::function<void ()> undo = [this ]() { executeCommand (new UndoCommand (this , activeEditor_)); } undoButton.setCommand (undo); shortcuts.onKeyPress ("ctrl+z" , undo); } void executeCommand (Command* c) { if (c->execute ()) history.push (c); else delete c; } void undo () { auto command = history.pop (); if (command) command->undo (); } };