备忘录模式 (Memento Pattern)
意图:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。
基础组件
- Originator (原发器):需要保存状态的对象
- Memento (备忘录):存储原发器的内部状态
- Caretaker (管理者):负责保存备忘录,但不能对备忘录内容进行操作或检查
继承/实现关系
Originator --> Memento (创建和恢复状态)
Caretaker --> Memento (保存备忘录)
应用场景
- 需要保存对象状态快照以便后续恢复
- 直接访问对象状态会破坏封装性
- 实现撤销/重做功能
C++ 实现(文本编辑器撤销功能)
#include <iostream>
#include <string>
#include <vector>
#include <memory>
/*
* 备忘录模式
* 意图:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。
* 基础组件:
* - Originator (原发器):需要保存状态的对象
* - Memento (备忘录):存储原发器的内部状态
* - Caretaker (管理者):负责保存备忘录,但不能对备忘录内容进行操作或检查
* 继承/实现关系:
* Memento 负责创建和恢复 Originator 的状态,而 Caretaker 只负责保存和恢复 Memento。它们之间通过组合来实现。
*/
// 备忘录:存储文本状态
class TextMemento {
public:
explicit TextMemento(const std::string& content) : content_(content) {}
const std::string& getContent() const { return content_; }
private:
std::string content_;
};
// 原发器:文本编辑器
class TextEditor {
public:
void type(const std::string& text) {
content_ += text;
}
std::shared_ptr<TextMemento> save() const {
return std::make_shared<TextMemento>(content_);
}
void restore(const std::shared_ptr<TextMemento>& memento) {
if (memento) {
content_ = memento->getContent();
}
}
void print() const {
std::cout << "Current content: " << content_ << "\n";
}
private:
std::string content_;
};
// 管理者:历史记录
class History {
public:
void push(const std::shared_ptr<TextMemento>& state) {
history_.push_back(state);
}
std::shared_ptr<TextMemento> pop() {
if (history_.empty()) {
return nullptr;
}
auto last = history_.back();
history_.pop_back();
return last;
}
private:
std::vector<std::shared_ptr<TextMemento>> history_;
};
void MementoPattern()
{
std::cout << std::string(13, '-') << " Memento Pattern " << std::string(13, '-') << "\n";
TextEditor editor;
History history;
editor.type("Hello, ");
history.push(editor.save()); // 保存状态1
editor.type("world!");
history.push(editor.save()); // 保存状态2
editor.type(" How are you?");
editor.print(); // 输出:Hello, world! How are you?
// 撤销一次
editor.restore(history.pop());
editor.print(); // 输出:Hello, world!
// 再撤销一次
editor.restore(history.pop());
editor.print(); // 输出:Hello,
}
组件对应关系
TextEditor→ 原发器TextMemento→ 备忘录History→ 管理者
913

被折叠的 条评论
为什么被折叠?



