设计模式笔记-Memento模式

备忘录模式:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。备忘的用例很多,比如word编辑,按ctrl+z撤消,如果没备忘,肯定是不能撤消回到之前状态的;打过游戏的人应该也了解,比如DOTA1,技术挺落后,不像DOTA2断线可以重连,比赛的时候为了防止游戏崩溃,时不时的裁判要手动保存游戏。


这里的Memento类保存的是Originator类的一个临时状态,它自己是不可以变化的--本来就是要保存原来状态,又被改变了那不是没意义了?所以这里我把Memento类的所有成员都设为private的,然后把Originator设为友元类,这样它就只能被Originator访问了。这个应该是个关注点,但看网上好多人没有这么弄,成员函数都是public的,可能很多人觉得只要我不去调用它不就行了嘛,违反了迪米特法则?“一个对象应该对其他对象保持最少的了解”,这就是设计的精妙。

还有一点就是:为了在Originator类中创建备忘,设计了备忘类Memento的一个带Originator*类型参数的拷贝构造函数!

//originator.h

#include<string>
#include "memento.h"

class Memento;
class Originator {
public:
	Memento* createMemento();

	void restoreMemento(Memento *);

	void setState(string state)	{
		_state = state;
	}
	string getState() {
		return _state;
	}
private:
	std::string _state;
};
//originator.cpp

void Originator::restoreMemento(Memento *m) {
	_state = m->getState();
}
Memento* Originator::createMemento() {
	return new Memento(this);
}
//memento.h
#include"originator.h"
#include<string>

class Originator;
class Memento {
	friend class Originator;
private:
	Memento(Originator*);

	void setState(std::string state) {
		_state = state;
	}
	std::string getState() {
		return _state;
	}

private:
	std::string _state;
};
//memento.cpp
#include "memento.h"
Memento::Memento(Originator *o) {
	_state = o->getState();
}
完全可以不用Caretaker类,此时用户代码需要自己处理备份多状态逻辑(用容器)。 简单的实现如下:

class Caretaker {
	void Save(Memento *lpMemento) {
		m_vectMemento.push_back(lpMemento);
	}

	Memento* Load(int idx) {	//这里随便你怎么实现吧
		return m_vectMemento[idx];
	}

private:
	vector<Memento*> m_vectMemento;
};
用户代码:

int main()
{
	Originator originator;
	originator.setState("old");
	Memento * meme = originator.createMemento();
	originator.setState("new");
	originator.restoreMemento(meme);

	//使用Caretaker类也可以
	Originator originator;
	Caretaker take;
	originator.setState("old");
	Memento * meme = originator.createMemento();
	take.Save(meme);
	originator.setState("new");
	originator.restoreMemento(take.Load(0));
	return 0;
}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值