备忘录模式

备忘录模式,如它的名字所说,就是为了备忘的。以下很多内容来自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打印状态

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值