备忘录模式
Without violating encapsulation,capture and externalize an object’s internal state so that the object can be restored to this state later.
(在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。)
通用类图
发起人角色类
记录当前时刻的内部状态,负责定义哪些属于备份范围的状态,负责创建和恢复备忘录数据
备忘录角色类
负责存储发起人对象的内部状态,在需要的时候提供发起人需要的内部状态
备忘录管理员角色类
对备忘录进行管理、保存和提供备忘录
通用源码
//发起人角色类
class Originator {
public:
//set和get
string getState() { return state; }
void setState(string s) { state = s; }
//创建备忘录
Memento* createMemento() {
return new Memento(state);
}
//恢复备忘录
void restoreMemento(Memento m) {
setState(m.getState());
}
private:
//内部状态
string state;
};
//备忘录角色类
class Memento {
public:
//构造函数传递参数
Memento(string s) {
state = s;
}
string getState() {
return state;
}
void setState(string s) {
state = s;
}
private:
//发起人的内部状态
string state;
};
//备忘录管理员角色类
class Caretaker {
public:
Memento getMemento() {
return *memento;
}
void setMemento(Memento m) {
memento = &m;
}
private:
//备忘录对象
Memento* memento;
};
使用场景
需要保存和恢复数据的相关状态场景
提供一个可回滚的操作
需要监控的副本场景中
数据库连接的事务管理
注意事项
备忘录的生命期,要主动管理,建立就要使用,不使用就删除
备忘录的性能,不要在频繁建立备份的场景中使用备忘录模式
扩展
clone方式的备忘录
多状态的备忘录模式
多备份的备忘录
最佳实践
可以利用备忘录模式给数据库减压
示例代码
#include <iostream>
#include <string>
using namespace std;
class Memento {
public:
Memento(string s) {
state = s;
}
string getState() {
return state;
}
void setState(string s) {
state = s;
}
private:
string state;
};
class Caretaker {
public:
Memento getMemento() {
return *memento;
}
void setMemento(Memento m) {
memento = &m;
}
private:
Memento* memento;
};
class Boy {
public:
void changeState() {
state = "bad";
}
string getState() {
return state;
}
void setState(string s) {
state = s;
}
Memento* createMemento() {
return new Memento(state);
}
void restoreMemento(Memento m) {
setState(m.getState());
}
private:
string state;
};
int main() {
Boy b;
Caretaker c;
b.setState("good");
cout << "Before current state: " << b.getState() << endl;
c.setMemento(*(b.createMemento()));
b.changeState();
cout << "After current state: " << b.getState() << endl;
b.restoreMemento(c.getMemento());
cout << "Restore current state: " << b.getState() << endl;
return 0;
}