备忘录模式(Memento Pattern):在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。
别名
Token
适用性
在以下情况下使用备忘录模式:
1)必须保存一个对象在某一个时刻的 (部分) 状态, 这样以后需要时它才能恢复到先前的状态。
2)如果一个用接口来让其它对象直接得到这些状态,将会暴露对象的实现细节并破坏对象的封装性。
结构
参与者
Memento
——备忘录存储原发器对象的内部状态。原发器根据需要决定备忘录存储原发器的哪些内部状态。
——防止原发器以外的其他对象访问备忘录。备忘录实际上有两个接口,管理者(caretaker)只能看到备忘录的窄接口,它只能将备忘录传递给其他对象。相反,原发器能够看到一个宽接口, 允许它访问返回到先前状态所需的所有数据。理想的情况是只允许生成本备忘录的那个原发器访问本备忘录的内部状态。
Originator
——原发器创建一个备忘录,用以记录当前时刻它的内部状态。
——使用备忘录恢复内部状态。
Caretaker
——负责保存好备忘录。
——不能对备忘录的内容进行操作或检查。
协作
管理器向原发器请求一个备忘录 , 保留一段时间后 , 将其送回给原发器。 备忘录是被动的,只有创建备忘录的原发器会对它的状态进行赋值和检索。
1)保持封装边界
2)简化原发器
3)使用备忘录可能代价很高
4)定义窄接口和宽接口
5)维护备忘录的潜在代价。
实现
1)语言支持备忘录有两个接口:一个为原发器所使用的宽接口,一个为其他对象所使用的窄接口。
相关模式
别名
Token
适用性
在以下情况下使用备忘录模式:
1)必须保存一个对象在某一个时刻的 (部分) 状态, 这样以后需要时它才能恢复到先前的状态。
2)如果一个用接口来让其它对象直接得到这些状态,将会暴露对象的实现细节并破坏对象的封装性。
结构
参与者
Memento
——备忘录存储原发器对象的内部状态。原发器根据需要决定备忘录存储原发器的哪些内部状态。
——防止原发器以外的其他对象访问备忘录。备忘录实际上有两个接口,管理者(caretaker)只能看到备忘录的窄接口,它只能将备忘录传递给其他对象。相反,原发器能够看到一个宽接口, 允许它访问返回到先前状态所需的所有数据。理想的情况是只允许生成本备忘录的那个原发器访问本备忘录的内部状态。
Originator
——原发器创建一个备忘录,用以记录当前时刻它的内部状态。
——使用备忘录恢复内部状态。
Caretaker
——负责保存好备忘录。
——不能对备忘录的内容进行操作或检查。
协作
管理器向原发器请求一个备忘录 , 保留一段时间后 , 将其送回给原发器。 备忘录是被动的,只有创建备忘录的原发器会对它的状态进行赋值和检索。
1)保持封装边界
2)简化原发器
3)使用备忘录可能代价很高
4)定义窄接口和宽接口
5)维护备忘录的潜在代价。
实现
1)语言支持备忘录有两个接口:一个为原发器所使用的宽接口,一个为其他对象所使用的窄接口。
2)存储增量式改变 如果备忘录的创建及其返回(给它们的原发器)的顺序是可预测的,备忘录可以仅存储原发器内部状态的增量改变。
参考代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Mymemento
{
class Originator
{
private string state;
public string State
{
get { return state; }
set { state = value; }
}
// 创建备忘录
public Memento CreateMemento()
{
return (new Memento(state));
}
// 恢复备忘录
public void SetMemento(Memento memento)
{
state = memento.State;
}
public void ShowState()
{
Console.WriteLine("State=" + state);
}
}
class Memento
{
private string state;
public string State
{
get { return state; }
}
// 导入数据
public Memento(string state)
{
this.state = state;
}
}
class Caretaker
{
private Memento m;
public Memento M // 管理备忘录
{
get { return m; }
set { m = value; }
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Mymemento
{
class Program
{
static void Main(string[] args)
{
Originator o = new Originator();
o.State = "On";
o.ShowState();
Caretaker c = new Caretaker();
c.M = o.CreateMemento();
o.State = "Off";
o.ShowState();
o.SetMemento(c.M);
o.ShowState();
Console.ReadKey();
}
}
}
游戏存档参考代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Mymemento2
{
class GameRole
{
private int vit;
public int Viatlity
{
get { return vit; }
set { vit = value; }
}
private int atk;
public int Attack
{
get { return atk; }
set { atk = value; }
}
private int def;
public int Defense
{
get { return def; }
set { def = value; }
}
public void GetInitState()
{
this.vit = 100;
this.atk = 100;
this.def = 100;
}
public void Fight()
{
this.vit = 0;
this.atk = 0;
this.def = 0;
}
public void StateDisplay()
{
Console.WriteLine("The role current state:");
Console.WriteLine("Viatlity:{0}", vit);
Console.WriteLine("Attack:{0}", atk);
Console.WriteLine("Defense:{0}", def);
Console.WriteLine();
}
public RoleStateMemento SaveState()
{
return (new RoleStateMemento(vit, atk, def));
}
public void RecoveryState(RoleStateMemento memento)
{
this.vit = memento.Viatlity;
this.atk = memento.Attack;
this.def = memento.Defense;
}
}
class RoleStateMemento
{
private int vit;
public int Viatlity
{
get { return vit; }
set { vit = value; }
}
private int atk;
public int Attack
{
get { return atk; }
set { atk = value; }
}
private int def;
public int Defense
{
get { return def; }
set { def = value; }
}
public RoleStateMemento(int vit, int atk, int def)
{
this.vit = vit;
this.atk = atk;
this.def = def;
}
}
class RoleStateCaretaker
{
private RoleStateMemento m;
public RoleStateMemento M
{
get { return m; }
set { m = value; }
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Mymemento2
{
class Program
{
static void Main(string[] args)
{
GameRole gr = new GameRole();
gr.GetInitState();
gr.StateDisplay();
RoleStateCaretaker stateAdmin = new RoleStateCaretaker();
stateAdmin.M = gr.SaveState();
gr.Fight();
gr.StateDisplay();
gr.RecoveryState(stateAdmin.M);
gr.StateDisplay();
Console.ReadKey();
}
}
}
相关模式