命令模式:
**定义:**命令模式是一种行为型设计模式,它将一个请求封装成一个对象,从而允许使用不同的请求、队列或日志请求,并支持可撤销的操作。命令模式的核心思想是将请求的发送者与请求的接收者解耦,使得请求的发送者无需知道接收者的具体实现,从而提高了系统的灵活性和可维护性。
备忘录模式:
**定义:**备忘录模式是一种行为型设计模式,也叫做快照模式(Snapshot),它允许在不破坏封装的前提下,捕获一个对象的内部状态,并在对象之外保存这个状态。备忘录模式主要用于实现撤销机制、版本控制、历史记录等功能。
**应用:**命令模式和备忘录模式在实现undo和redo功能时都发挥着重要作用。命令模式通过封装请求和提供撤销方法来实现撤销和重做功能;而备忘录模式则通过保存对象的状态来实现撤销和重做功能。在实际应用中,这两种模式可以相互结合使用,以构建更加灵活和可维护的系统。例如,在命令模式中引入备忘录模式来保存命令执行前后的状态,从而更方便地实现撤销和重做功能。
代码:
cpp
// 接收者类,包含可以执行的状态
class Receiver {
private:
std::string state;
public:
std::string getState() const { return state; }
void setState(const std::string& newState) { state = newState; }
};
// 定义一个接口类,用于所有命令
class Command {
public:
virtual ~Command() = default;
virtual void execute() = 0;
virtual void undo() = 0;
};
// 具体的命令类
class ConcreteCommand : public Command {
private:
std::shared_ptr<Receiver> receiver;
std::string previousState;
std::string newState;
public:
ConcreteCommand(std::shared_ptr<Receiver> r, const std::string& state)
: receiver(r), newState(state) {}
void execute() override {
previousState = receiver->getState();
receiver->setState(newState);
std::cout << "Executed: " << newState << std::endl;
}
void undo() override {
receiver->setState(previousState);
std::cout << "Undone: " << previousState << std::endl;
}
};
// 调用者类,包含撤销和重做功能的实现
class Invoker {
private:
std::stack<std::shared_ptr<Command>> undoStack;
std::stack<std::shared_ptr<Command>> redoStack;
public:
void executeCommand(std::shared_ptr<Command> command) {
command->execute();
undoStack.push(command);
while (!redoStack.empty()) // 执行新命令时清空重做栈
{
redoStack.pop();
}
}
void undo() {
if (!undoStack.empty()) {
auto command = undoStack.top();
undoStack.pop();
command->undo();
redoStack.push(command);
} else {
std::cout << "No more commands to undo." << std::endl;
}
}
void redo() {
if (!redoStack.empty()) {
auto command = redoStack.top();
redoStack.pop();
command->execute();
undoStack.push(command);
} else {
std::cout << "No more commands to redo." << std::endl;
}
}
};
int main() {
std::shared_ptr<Receiver> receiver = std::make_shared<Receiver>();
Invoker invoker;
receiver->setState("State1");
invoker.executeCommand(std::make_shared<ConcreteCommand>(receiver, "State2"));
invoker.executeCommand(std::make_shared<ConcreteCommand>(receiver, "State3"));
invoker.undo();
invoker.undo();
invoker.redo();
return 0;
}