C++备忘录模式:游戏存档实战解析
备忘录模式(Memento Pattern)的核心概念
备忘录模式是一种行为设计模式,允许在不破坏封装性的前提下捕获并外部化一个对象的内部状态,以便在需要时恢复该状态。该模式通过三个核心角色实现:Originator(原发器)、Memento(备忘录)和Caretaker(管理者)。
角色定义与协作
Originator:需要保存和恢复状态的对象。它创建一个备忘录以保存当前状态,并可使用备忘录恢复之前的状态。
Memento:存储Originator的内部状态。备忘录的设计需防止除Originator外的其他对象访问其内容。
Caretaker:负责保存和管理备忘录,但不能修改或检查备忘录内容。它仅负责将备忘录传递给Originator。
C++实现示例
以下是一个完整的C++实现示例,展示如何通过备忘录模式实现游戏存档功能:
#include <iostream>
#include <string>
#include <vector>
// Memento类
class Memento {
private:
std::string state;
friend class Game; // 仅允许Game类访问私有成员
Memento(const std::string& state) : state(state) {}
std::string GetState() const { return state; }
};
// Originator类
class Game {
private:
std::string state; // 游戏状态(如关卡、分数等)
public:
void SetState(const std::string& state) {
this->state = state;
}
const std::string& GetState() const {
return state;
}
Memento* SaveState() {
return new Memento(state);
}
void RestoreState(const Memento* memento) {
state = memento->GetState();
}
};
// Caretaker类
class GameHistory {
private:
std::vector<Memento*> mementos;
Game* game;
public:
GameHistory(Game* game) : game(game) {}
~GameHistory() {
for (auto memento : mementos) delete memento;
}
void Save() {
mementos.push_back(game->SaveState());
}
void Undo() {
if (!mementos.empty()) {
game->RestoreState(mementos.back());
mementos.pop_back();
}
}
};
// 客户端代码
int main() {
Game game;
GameHistory history(&game);
game.SetState("Level 1 - Score: 100");
history.Save();
game.SetState("Level 2 - Score: 200");
history.Save();
game.SetState("Level 3 - Score: 300");
std::cout << "Current State: " << game.GetState() << std::endl;
history.Undo();
std::cout << "After Undo: " << game.GetState() << std::endl;
history.Undo();
std::cout << "After Undo: " << game.GetState() << std::endl;
return 0;
}
实现要点解析
-
封装性保护:通过将
Memento的构造函数和GetState方法设为私有,并声明Game为友元类,确保只有Originator能访问备忘录的内部状态。 -
状态管理:
Caretaker(GameHistory)通过栈结构管理备忘录,支持多次撤销操作。注意在析构函数中释放动态分配的备忘录对象。 -
扩展性:若需保存复杂状态(如多个变量),可将
Memento改为存储结构化数据(如JSON或二进制格式)。
应用场景与优势
典型场景:
- 需要实现撤销/重做功能的应用(如文本编辑器、图形软件)。
- 游戏存档/读档系统。
- 事务回滚机制(如数据库操作)。
核心优势:
- 保持对象封装边界,不暴露内部实现细节。
- 简化Originator的职责,状态管理由独立类处理。
- 支持历史状态追溯,符合单一职责原则。
与其他模式的对比
与命令模式:命令模式通过封装操作实现撤销,而备忘录模式直接存储状态。两者可结合使用,命令对象可调用备忘录保存状态。
与原型模式:原型模式通过克隆对象实现状态保存,但可能复制不必要的数据;备忘录模式仅保存必要状态,更轻量。
高级应用:增量备忘录
对于大型对象,可优化为仅保存状态变化部分(增量备忘录):
class IncrementalMemento {
private:
std::string deltaState; // 仅存储变化的部分
// ...其余实现类似基础备忘录
};
此变体节省内存,但增加了实现复杂度,需Originator能处理增量状态。
总结
备忘录模式通过状态外部化实现了优雅的撤销机制,其C++实现需特别注意封装性和内存管理。合理运用该模式可增强系统的可维护性,尤其适合需要状态回溯的场景。实际开发中应根据状态复杂度选择基础或变体实现。
BbS.okane346.info/PoSt/1121_942705.HtM
BbS.okane347.info/PoSt/1121_581652.HtM
BbS.okane348.info/PoSt/1121_746913.HtM
BbS.okane349.info/PoSt/1121_840055.HtM
BbS.okane350.info/PoSt/1121_123390.HtM
BbS.okane351.info/PoSt/1121_032985.HtM
BbS.okane352.info/PoSt/1121_854407.HtM
BbS.okane353.info/PoSt/1121_778202.HtM
BbS.okane354.info/PoSt/1121_878920.HtM
BbS.okane355.info/PoSt/1121_059474.HtM
BbS.okane346.info/PoSt/1121_668924.HtM
BbS.okane347.info/PoSt/1121_539233.HtM
BbS.okane348.info/PoSt/1121_856935.HtM
BbS.okane349.info/PoSt/1121_371258.HtM
BbS.okane350.info/PoSt/1121_901595.HtM
BbS.okane351.info/PoSt/1121_531527.HtM
BbS.okane352.info/PoSt/1121_338154.HtM
BbS.okane353.info/PoSt/1121_917780.HtM
BbS.okane354.info/PoSt/1121_965123.HtM
BbS.okane355.info/PoSt/1121_854979.HtM
BbS.okane346.info/PoSt/1121_164832.HtM
BbS.okane347.info/PoSt/1121_781525.HtM
BbS.okane348.info/PoSt/1121_106891.HtM
BbS.okane349.info/PoSt/1121_652625.HtM
BbS.okane350.info/PoSt/1121_475635.HtM
BbS.okane351.info/PoSt/1121_338434.HtM
BbS.okane352.info/PoSt/1121_741034.HtM
BbS.okane353.info/PoSt/1121_219732.HtM
BbS.okane354.info/PoSt/1121_103304.HtM
BbS.okane355.info/PoSt/1121_831342.HtM
BbS.okane346.info/PoSt/1121_635981.HtM
BbS.okane347.info/PoSt/1121_655577.HtM
BbS.okane348.info/PoSt/1121_798830.HtM
BbS.okane349.info/PoSt/1121_315354.HtM
BbS.okane350.info/PoSt/1121_847572.HtM
BbS.okane351.info/PoSt/1121_139169.HtM
BbS.okane352.info/PoSt/1121_797572.HtM
BbS.okane353.info/PoSt/1121_037588.HtM
BbS.okane354.info/PoSt/1121_680971.HtM
BbS.okane355.info/PoSt/1121_167490.HtM
BbS.okane346.info/PoSt/1121_717050.HtM
BbS.okane347.info/PoSt/1121_790193.HtM
BbS.okane348.info/PoSt/1121_172702.HtM
BbS.okane349.info/PoSt/1121_286390.HtM
BbS.okane350.info/PoSt/1121_814250.HtM
BbS.okane351.info/PoSt/1121_837448.HtM
BbS.okane352.info/PoSt/1121_922485.HtM
BbS.okane353.info/PoSt/1121_764103.HtM
BbS.okane354.info/PoSt/1121_729758.HtM
BbS.okane355.info/PoSt/1121_447209.HtM
BbS.okane346.info/PoSt/1121_082290.HtM
BbS.okane347.info/PoSt/1121_897191.HtM
BbS.okane348.info/PoSt/1121_748860.HtM
BbS.okane349.info/PoSt/1121_220179.HtM
BbS.okane350.info/PoSt/1121_658689.HtM
BbS.okane351.info/PoSt/1121_699978.HtM
BbS.okane352.info/PoSt/1121_030533.HtM
BbS.okane353.info/PoSt/1121_385386.HtM
BbS.okane354.info/PoSt/1121_797431.HtM
BbS.okane355.info/PoSt/1121_069020.HtM
BbS.okane356.info/PoSt/1121_703945.HtM
BbS.okane357.info/PoSt/1121_916078.HtM
BbS.okane358.info/PoSt/1121_116003.HtM
BbS.okane359.info/PoSt/1121_082382.HtM
BbS.okane360.info/PoSt/1121_270158.HtM
BbS.okane361.info/PoSt/1121_307651.HtM
BbS.okane362.info/PoSt/1121_399525.HtM
BbS.okane363.info/PoSt/1121_520345.HtM
BbS.okane365.info/PoSt/1121_271848.HtM
BbS.okane366.info/PoSt/1121_367623.HtM
BbS.okane356.info/PoSt/1121_247604.HtM
BbS.okane357.info/PoSt/1121_694504.HtM
BbS.okane358.info/PoSt/1121_832647.HtM
BbS.okane359.info/PoSt/1121_978312.HtM
BbS.okane360.info/PoSt/1121_113825.HtM
BbS.okane361.info/PoSt/1121_008148.HtM
BbS.okane362.info/PoSt/1121_839109.HtM
BbS.okane363.info/PoSt/1121_444593.HtM
BbS.okane365.info/PoSt/1121_750276.HtM
BbS.okane366.info/PoSt/1121_467859.HtM