简介
备忘录模式:
在不破坏封装性的前提下,捕捉一个对象的内部状态,并在该对象外保存这个状态,这样以后就可将该对象恢复到原先保存的状态。
构成
1.originator(发起人):负责创建一个备忘录memento,用以记录当前时刻自身的内部状态,并可以使用备忘录恢复内部状态。originator可以根据需要决定memento储存自己的哪些内部状态。
2.memento(备忘录):负责存储originator对象的内部状态,并可以防止originator以外的其他对象访问备忘录。
3.caretaker(管理者):负责管理备忘录memento,但不能memento的内容进行访问或者操作。
常用的场景
需要提供保存和恢复数据的相关状态场景
提供一个可回滚rollback操作
需要监控的副本场景。
数据库连接的事务管理就是备忘录模式
优点
1.有时一些发起人对象的内部信息必须保存在发起人对象以外的地方,但是必须要由发起人对象自己读取,这时,使用备忘录模式可以把复杂的发起人内部信息对其他的对象屏蔽起来,从而可以恰当地保持封装的边界。
2.本模式简化了发起人类。发起人不再需要管理和保存其内部状态的一个个版本,客户端可以自行管理他们所需要的这些状态的版本。
3.当发起人角色的状态改变的时候,有可能这个状态无效,这时候就可以使用暂时存储起来的备忘录将状态复原。
缺点
1.如果发起人角色的状态需要完整地存储到备忘录对象中,那么在资源消耗上面备忘录对象会很昂贵。
2.当负责人角色将一个备忘录 存储起来的时候,负责人可能并不知道这个状态会占用多大的存储空间,从而无法提醒用户一个操作是否很昂贵。
3.当发起人角色的状态改变的时候,有可能这个协议无效。如果状态改变的成功率不高的话,不如采取“假如”协议模式。
注意事项
备忘录的声明期:作用在最近的代码。不使用就立即删除。..备忘录不是华佗在世,起死回生
备忘录的性能:不能用在for中,不能用频繁建立。消耗资源太多,这会是设计重构的前兆
测试代码
#include <iostream>
#include <assert.h>
#include <vector>
using namespace std;
//备份类
class FMemBook
{
public:
};
//管理类
class FTaker
{
public:
FMemBook m_pBook;
};
//发起者
class FOriginBookWirte
{
public:
FMemBook createMem();
void getMem(FMemBook* book);
};
void main()
{
FOriginBookWirte writer;
FTaker taker;
taker.m_pBook = writer.createMem(); //做备份
writer.getMem(&taker.m_pBook); //获取备份
}