备忘录模式(Memento Pattern)在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样可以在以后将对象恢复到原先保存的状态。
使用情景:很多时候我们总是需要记录一个对象的内部状态,这样做的目的就是为了允许用户取消不确定或者错误的操作,能够恢复到他原先的状态,使得他有"后悔药"可吃。
解决方法:通过一个备忘录类专门存储对象状态。
UML图:
备忘录模式包含以下几个角色:
Originator: 原发器。负责创建一个备忘录,用以记录当前对象的内部状态,通过也可以使用它来利用备忘录恢复内部状态。同时原发器还可以根据需要决定Memento存储Originator的那些内部状态。 Memento: 备忘录。用于存储Originator的内部状态,并且可以防止Originator以外的对象访问Memento。在备忘录Memento中有两个接口,其中Caretaker只能看到备忘录中的窄接口,它只能将备忘录传递给其他对象。Originator可以看到宽接口,允许它访问返回到先前状态的所有数据。 Caretaker: 负责人。负责保存好备忘录,不能对备忘录的内容进行操作和访问,只能够将备忘录传递给其他对象。
实例:
先创建一个origin角色,属性分别是dijiang、1,然后创建备忘录备份,然后将origin的属性重新设为liyf、2,最后通过备忘录将origin的状态恢复最原始状态,达到“反悔”的效果。
完整可运行代码:
#include<iostream> #include<memory> #include<string> using namespace std; //备忘录类,保存状态 class Memento { public: Memento(string state, int value) { maState = state; maValue = value; } const string& getState() { return maState; } const int getValue() { return maValue; } private: string maState; int maValue; }; //保存备忘录的类 class Caretaker { public: void setMemento(shared_ptr<Memento> memento) { maMemento = memento; } shared_ptr<Memento> getMemento(){ return maMemento; } private: shared_ptr<Memento> maMemento; }; //要备份的类 class Origin { public: void disPlay() { cout << maState << ": " << maValue << endl; } void setState(string state) { maState = state; } void setValue(int value) { maValue = value; } //根据备忘录类恢复状态 void recovery(shared_ptr<Memento> mem) { this->maState = mem->getState(); this->maValue = mem->getValue(); } //创建备忘录,保存状态 shared_ptr<Memento> createMemento() { return make_shared<Memento>(maState, maValue); } private: string maState; int maValue; }; int main() { Origin origin; origin.setState("dijiang"); origin.setValue(1); origin.disPlay(); cout << "-----back up ing-----" << endl; Caretaker caretaker; caretaker.setMemento(origin.createMemento()); origin.setState("liyf"); origin.setValue(2); origin.disPlay(); cout << "set to origin value" << endl; origin.recovery(caretaker.getMemento()); origin.disPlay(); return 0; } 运行截图: