一 使用场景 我们玩游戏时都会保存进度,所保存的进度以文件的形式存在。这样下次就可以继续玩,而不用从头开始。这里的进度其实就是游戏的内部状态,而这里的文件相当于是在游戏之外保存状态。这样,下次就可以从文件中读入保存的进度,从而恢复到原来的状态。这就是备忘录模式。
二 定义 备忘录模式 Memento Pattern:在不破坏封装的前提下,捕获一个对象的内部状体,并在该对象之外保存这个状态,这样可以在以后将对象恢复到原先保存的状态。它是一种对象行为型模。 Originator 原发器:它是一个普通类,可以创建一个备忘录,并存储它的当前内部状态,也可以使用备忘录来恢复其内部状态,一般将需要保存内部状态的类设计为原发器。
Memento 备忘录:存储原发器的内部状态,根据原发器来决定保存哪些内部状态。备忘录的设计一般可以参考原发器的设计,根据实际需要确定备忘录类中的属性。需要注意的是,除了原发器本身与负责人类之外,备忘录对象不能直接供其他类使用,原发器的设计在不同的编程语言中实现机制会有所不同。
Caretaker 负责人:负责人又称为管理者,它负责保存备忘录,但是不能对备忘录的内容进行操作或检查。在负责人类中可以存储一个或多个备忘录对象,它只负责存储对象,而不能修改对象,也无须知道对象的实现细节。
三 C++实现备忘录模式 GameRole.h
#pragma once #include <iostream> #include "RoleStateMemento.h" using namespace std; class GameRole { public: GameRole():m_blood(100){} RoleStateMemento * SaveState(){ return new RoleStateMemento(m_blood); } void RecoveryState(RoleStateMemento * _rolestate){ m_blood = _rolestate->getBloodValue(); std::cout << "recovery..." << std::endl; } void showState(){ std::cout << "blood: " << m_blood << std::endl; } void Fight(){ m_blood -= 10; } private: unsigned m_blood; };RoleStateMemento.h
#pragma once #include <iostream> using namespace std; class RoleStateMemento { public: RoleStateMemento(unsigned _blood):m_blood(_blood){} private: friend class GameRole; unsigned getBloodValue(){ return m_blood; } unsigned m_blood; };Caretaker.h
#pragma once #include "RoleStateMemento.h" class CareTaker { public: CareTaker(){} virtual ~CareTaker(){} void setRoleStateMemento(RoleStateMemento * _sm){ state_memento = _sm; } RoleStateMemento * getRoleStateMemento(){ return state_memento; } private: RoleStateMemento * state_memento; };main.cpp
#include <iostream> #include "GameRole.h" #include "Caretaker.h" using namespace std; int main() { GameRole * roler = new GameRole(); roler->showState(); CareTaker * caretaker = new CareTaker(); caretaker->setRoleStateMemento(roler->SaveState()); roler->Fight(); roler->showState(); roler->RecoveryState(caretaker->getRoleStateMemento()); roler->showState(); system("pause"); return 0; }四 总结 优点: 1 提供状态恢复机制,可以回到特定的历史步骤。 2 备忘录实现了对信息的封装,一个备忘录表示一个状态。
缺点: 1 资源消耗过大,变量多的话会不可避免的占用大量空间。
