模式定义
备忘录模式(Memento Pattern)是一种行为型设计模式,其核心是在不破坏对象封装性的前提下,捕获并保存对象的内部状态,以便后续恢复。该模式特别适用于需要实现撤销/重做、状态回滚等功能的系统,如数控系统的加工状态保存与恢复。
模式结构
发起人(Originator)
- 负责创建备忘录(保存当前状态)和从备忘录恢复状态。
备忘录(Memento) - 存储发起人的内部状态,仅允许发起人访问其数据。
管理者(Caretaker) - 保存和管理备忘录,但不修改其内容。
适用场景
数控系统状态保存:如加工参数(坐标、速度)的备份与恢复。
操作撤销/重做:用户误操作后回滚到历史状态。
系统故障恢复:异常停机时恢复至安全状态。
C++示例(数控系统场景)
场景说明:
数控机床在加工过程中需要保存当前状态(坐标、速度),当发生异常时恢复至最近一次保存的状态。
cpp
#include
#include
#include
// 备忘录:保存数控系统状态
class CNCStateMemento {
private:
std::string position_; // 坐标
double speed_; // 速度
public:
CNCStateMemento(std::string pos, double speed)
: position_(pos), speed_(speed) {}
// 仅允许Originator访问(友元类)
friend class CNCMachine;
};
// 发起人:数控机床
class CNCMachine {
private:
std::string position_;
double speed_;
public:
void setState(std::string pos, double speed) {
position_ = pos;
speed_ = speed;
}
CNCStateMemento* saveState() {
return new CNCStateMemento(position_, speed_);
}
void restoreState(CNCStateMemento* memento) {
position_ = memento->position_;
speed_ = memento->speed_;
std::cout << "恢复至状态:坐标=" << position_
<< ",速度=" << speed_ << std::endl;
}
void display() const {
std::cout << "当前状态:坐标=" << position_
<< ",速度=" << speed_ << std::endl;
}
};
// 管理者:状态历史记录
class CNCCaretaker {
private:
std::vector history_;
public:
void addMemento(CNCStateMemento* memento) {
history_.push_back(memento);
}
CNCStateMemento* getLastMemento() {
if (history_.empty()) return nullptr;
CNCStateMemento* last = history_.back();
history_.pop_back();
return last;
}
};
// 客户端使用示例
int main() {
CNCMachine machine;
CNCCaretaker caretaker;
// 设置初始状态并保存
machine.setState("X100 Y200", 1500);
caretaker.addMemento(machine.saveState());
machine.display(); // 输出当前状态
// 修改状态(模拟异常操作)
machine.setState("X150 Y250", 2000);
std::cout << "异常操作后:";
machine.display();
// 恢复至最近保存的状态
CNStateMemento* lastState = caretaker.getLastMemento();
if (lastState) {
machine.restoreState(lastState);
machine.display();
}
return 0;
}
代码解析
CNCStateMemento:封装数控机床的坐标和速度,仅允许CNCMachine
访问(通过友元类)。
CNCMachine:作为发起人,提供saveState()
和restoreState()
方法实现状态保存与恢复。
CNCCaretaker:管理历史状态,支持撤销操作。
优势与局限
优势:
- 状态封装性良好,避免外部直接访问。
- 简化数控系统的状态管理逻辑。
局限: - 频繁保存状态可能导致内存占用高。