关闭

设计模式笔记-Memento模式

131人阅读 评论(0) 收藏 举报
分类:

备忘录模式:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。备忘的用例很多,比如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

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:41796次
    • 积分:935
    • 等级:
    • 排名:千里之外
    • 原创:44篇
    • 转载:9篇
    • 译文:0篇
    • 评论:1条
    有用博客
    dongas的博客:http://blog.chinaunix.net/space.php?uid=20643761 woshixingaaa的博客:http://blog.csdn.net/woshixingaaa singleboy的博客:http://singleboy.blog.163.com/ embededgood的博客:http://blog.chinaunix.net/space.php?uid=21289517
    最新评论