备忘录模式,如它的名字所说,就是为了备忘的。以下很多内容来自GOF的设计模式,不得不佩服,经典就是经典。
定义:
在不破坏封闭的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。用它保存对象的当
前状态,以便于恢复。它的很重要的一点是在外部保存。
意图:
很多时候为了允许用户的撤销操作,需要保存当前的状态信息到某一个地方,然后到需要恢复的时候再取出来。一般来说,对象封装了它的内部状态,
外部不应该去访问它,那么如何将一个对象的内部状态保存在其他地方呢?于是我们迎来了备忘录模式。
类图解释:
上面一共三个类:
Originator:原发器类,它创建一个备忘录,保存自己的状态到备忘录中,同时使用备忘录恢复自己的状态。
Memento:备忘录类,它存储原发器对象的内部状态。它提供了一个宽接口给原发器类,一个窄接口给负责人类。
CareTaker:负责人类,它保留着备忘录的引用,但是不能访问备忘录的内部。
协作图:
再看一下协作图就更明了:
当负责人需要保存原发器的状态时候,它调用原发器的CreateMemento接口,将返回的备忘录的指针保存下来,以便于恢复的时候使用。
原发器收到CreateMemento消息,它首先创建一个Memento对象,然后通过调用SetState将自己的状态传递给备忘录保存下来。
当负责人需要恢复原发器的状态的时候,它调用原发器的SetMemento接口,将存储的备忘录指针传递进去,原发器收到SetMemento消息,它根据传进来的Memento对象,调用Memento对象的GetState方法恢复原发器的状态。
代码:
Head文件
#ifndef __ORIGINATOR_H
#define __ORIGINATOR_H
typedef struct State
{
//int m_nState;
int m_nXpos;
int m_nYpos;
}State;//原发器需要保留自己的状态
class Memento;
//原发器,需要保存自己的状态到备忘录
class Originator
{
public:
virtual ~Originator(){}
Originator(){
m_sState.m_nXpos = 0;
m_sState.m_nYpos = 0;
}
static Originator* Instance();
Memento* CreateMemento();
void SetMemento(const Memento*);
void MoveTo(int, int);
void ShowState();
protected:
private:
State m_sState;
static Originator* m_pInstance;
};
//备忘录提供宽接口给原发器,窄接口给管理者
class Memento
{
public:
virtual ~Memento(){}
protected:
private:
friend class Originator;
Memento(){
m_sState.m_nXpos = 0;
m_sState.m_nYpos = 0;
}
void SetState(State s){
m_sState = s;//结构体复制
}
State GetState()const{
return m_sState;
}
State m_sState;
};
//管理者,负责保留着备忘录的指针
class MoveCommand
{
public:
MoveCommand():m_pMemento(0){}
void Execute();
void UnExecute();
void ShowState();
protected:
private:
Memento* m_pMemento;
};
#endif
Cpp文件:
#include "Originator.h"
#include <stdio.h>
//原发器是单例模式
Originator* Originator::m_pInstance = NULL;
Originator* Originator::Instance()
{
if(m_pInstance == NULL){
m_pInstance = new Originator();
}
return m_pInstance;
}
//保存自己的状态到备忘录
Memento* Originator::CreateMemento()
{
Memento* m = new Memento();
m->SetState(m_sState);
return m;//让备忘录帮忙保存它的状态
}
//从备忘录中恢复状态
void Originator::SetMemento(const Memento* m)
{
m_sState = m->GetState();
}
//更改当前原生的状态
void Originator::MoveTo(int x, int y)
{
m_sState.m_nXpos = x;
m_sState.m_nYpos = y;
}
void Originator::ShowState()
{
printf("State: %d, %d\n",m_sState.m_nXpos,m_sState.m_nYpos);
}
//管理者,使用原生器的创建备忘录,和从备忘录恢复的方法
void MoveCommand::Execute()
{
Originator* ot = Originator::Instance();
m_pMemento = ot->CreateMemento();
ot->MoveTo(1,2);
}
//取消命令
void MoveCommand::UnExecute()
{
Originator* ot = Originator::Instance();
ot->SetMemento(m_pMemento);
}
void MoveCommand::ShowState()
{
Originator* ot = Originator::Instance();
ot->ShowState();
}
main文件:
#include <iostream>
#include "Originator.h"
using namespace std;
int main()
{
MoveCommand mv;
mv.ShowState();
mv.Execute();
mv.ShowState();
mv.UnExecute();
mv.ShowState();
return 0;
}
输出:
解释main文件:
1,首先创建一个命令对象,
2,调用命令对象的展示状态方法,从而调用Originator的单例方法来创建对象并打印状态(Originator默认为0,0)
3,Execute执行移动命令,首先创建备忘录,保存它的引用,然后移动坐标
4,ShowState打印状态
5,UnExecute,取消命令,首先设置备忘录,从而调用备忘录的GetState方法,恢复状态
6,ShowState打印状态