[设计模式]备忘录模式(Memento)

1.意图

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

2.动机

       有时有必要记录一个对象的内部状态。为了允许用户取消不确定的操作或从错误中恢复过来,需要实现检查点和取消机制,你必须事先将状态信息保存在某处,这样才能将对象恢复到它们先前的状态。但是对象通常封装了其不封或所有的状态信息,使得其状态不能被其他对象访问,也就不可能在该对象之外保存其状态。而暴露其内部状态又将违反封装的原则,可能有损应用的可靠性和可扩展性。

3.结构与参与者


4.效果

1)保持封装边界

        使用备忘录就是为了封装原发其的信息,这样既可返回原来的状态,也使得信息不暴露。面向接口编程。

2)它简化了原发器

        在其他的保持封装性的设计中,Originator负责存储客户请求存储的原始状态。现在由Memento类进行存储。

3)使用备忘录可能代价很高(缺)

       如果存储的信息过大,或者操作过于频繁,那么开销会很大,此时备忘录模式就不太合适了。

4)定义窄接口和宽接口

       在一些语言中可能难以保证只有原发器可访问备忘录的状态。

5)维护备忘录的潜在代价(缺)

       管理器负责删除它所能维护的备忘录。然而管理器不知道备忘录中有多少个状态。因此当存储备忘录时,一个本来很小的管理器,可能会产生大量的存储开销。

5.实现

1)语言支持

        备忘录有两个接口:一个为原发其所使用的宽接口,一个为其他对象所使用的窄接口。理想的实现语言应可支持两级的静态保护。在C++中,可将Originator作为Memento的一个友元,并使Memento宽接口为私有,只有窄接口应该被声明为公共的。

2)存储增量式改变

         如果备忘录的创建及其返回(给它们的原发器)的顺序是可预测的,备忘录可以仅存储原发起内部状态的增量改变。

6.代码示例

#include <iostream>
#include <string>
using namespace std;

class Memo;
//封装的数据
class State
{
public:
	State(int health,int attack,int defense):m_health(health),m_attack(attack),m_defense(defense){}
	int GetHealth(){return m_health;}
	int GetAttack(){return m_attack;}
	int GetDefense(){return m_defense;}
	void SetHealth(int health){m_health=health;}
	void SetAttack(int attack){m_attack=attack;}
	void SetDefense(int defense){m_defense=defense;}
private:
	int m_health;
	int m_attack;
	int m_defense;
};
//发起人类
class Originator
{
public:
	Originator(State* state):_state(state){}
    Memo* CreateMemo();
	State* GetState()
	{
		return _state;
	}
	void SetMemo(Memo* memo);
	void Show()
	{
		cout<<"生命值:"<<_state->GetHealth()<<endl;
		cout<<"攻击力:"<<_state->GetAttack()<<endl;
		cout<<"防御力:"<<_state->GetDefense()<<endl;
	}
private:
	State* _state;
};

//备忘录类
class Memo
{
public:
	Memo(State* state)
	{
		_state=new State(state->GetHealth(),state->GetAttack(),state->GetDefense());
	}
private:
	friend class Originator;
	State* GetState()
	{
		return _state;
	}
	State* _state;
};

Memo* Originator::CreateMemo()
{
	return new Memo(_state);
}

void Originator::SetMemo(Memo* memo)
{
	_state = memo->GetState();
}

//管理者类
class Caretaker
{
public:
	Memo* memo;
};
//客户端:
int main()
{	
	void FightBoss(Originator* on);
	State* pState=new State(1000,200,100);
	Originator* on=new Originator(pState);
	Caretaker* ct=new Caretaker();
	cout << "人物初始化完成"<<endl;
	on->Show();
	ct->memo = on->CreateMemo();
	cout << "存档完成"<<endl;
	FightBoss(on);
	on->Show();
	cout << "加载存档"<<endl;
	on->SetMemo(ct->memo);
	on->Show();

	return 0;
}
void FightBoss(Originator* on)
{
	on->GetState()->SetHealth(0);
	on->GetState()->SetAttack(0);
	on->GetState()->SetDefense(0);
	cout << "对抗BOSS"<<endl;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值