Published on

设计模式(18)——备忘录 Memento

Authors
  • avatar
    Name
    Leon
    Twitter

十八、Memento(备忘录模式,别名 Token 对象行为模式)

1. 意图:

  在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。

2. 适用:

  1. 必须保存一个对象在某一个时刻的(部分)状态,这样以后需要时它才能恢复到先前的状态。
  2. 如果用一个接口来让其它对象直接得到这些状态,将会暴露对象的实现细节并破坏对象的封装性。

3. 效果:

  1. 保持封装边界
  2. 它简化了原发器
  3. 使用备忘录可能代价很高
  4. 定义窄口和宽接口
  5. 维护备忘录的潜在代价

4. 类图:

5. C++实现:

  1. 编写一个备忘录类 Memento,有一个 State 对象 _state,用于存储原发器对象的内部状态。
  2. 编写一个原发器类 Originator,有一个函数 Memento* CreateMemento();,用于创建一个备忘录,一个函数 void RestoreToMemento(Memento* mt); 用于恢复状态。
  3. Memento 中将Originator声明为友元类 friend class Originator,保证只有 Originator 可以访问 Memento 的内部信息,但其他类不能。
  4. Memento 的构造函数声明为私有的,保证只能由 Originator 通过 CreateMemento() 来创建。

Memento.h

//Memento.h
#pragma once
#include <string>
using namespace::std;

typedef string State;

class Memento {
public:
	~Memento();
private:
	//这是最关键的地方,将 Originator 声明为 friend 类,可以访问内部信息,但是其他类不能访问
	friend class Originator;
	Memento();
	Memento(const State& sdt);
	void SetState(const State& sdt);
	State GetState();
private:
	State _sdt;
};

Memento.cpp

//Memento.cpp
#include "Memento.h"

Memento::Memento() {}
Memento::Memento(const State& sdt) {
	_sdt = sdt;
}
Memento::~Memento(){}
State Memento::GetState() {
	return _sdt;
}
void Memento::SetState(const State& sdt) {
	_sdt = sdt;
}

Originator.h

//Originator.h
#pragma once

#include <string>
using namespace::std;

class Memento;

class Originator {
public:
	typedef string State;
	Originator();
	Originator(const State& sdt);
	~Originator();
	Memento* CreateMemento();
	void SetMemmento(Memento* men);
	void RestoreToMemento(Memento* mt);
	State GetState();
	void SetState(const State& sdt);
	void PrintState();
protected:
private:
	State _sdt;
	Memento* _mt;
};

Originator.cpp

//Originator.cpp
#include "Originator.h"
#include "Memento.h"

#include <iostream>
using namespace::std;

typedef string State;

Originator::Originator() {
	_sdt = "";
	_mt = 0;
}
Originator::Originator(const State& sdt) {
	_sdt = sdt;
	_mt = 0;
}
Originator::~Originator() {}

Memento* Originator::CreateMemento() {
	return new Memento(_sdt);
}

State Originator::GetState() {
	return _sdt;
}
void Originator::SetState(const State& sdt) {
	_sdt = sdt;
}
void Originator::PrintState() {
	cout << this->_sdt << "......" << endl;
}
void Originator::SetMemmento(Memento* men) {
	this->_mt = men;
}
void Originator::RestoreToMemento(Memento* mt) {
	this->_sdt = mt->GetState();
}

main.cpp

//main.cpp

#include "Memento.h"
#include "Originator.h"

#include <iostream>
using namespace::std;

int main(int argc, char* argv[]) {
	Originator* o = new Originator();
	o->SetState("old");	//备忘前状态
	o->PrintState();

	Memento* m = o->CreateMemento();	//将状态备忘
	o->SetState("new");	//修改状态
	o->PrintState();
	o->RestoreToMemento(m);	//恢复修改前状态
	o->PrintState();

	return 0;
}