Memento模式的关键就是要在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可以利用该保存的状态实施恢复操作。
Originator(原发器):创建一个备忘录,并存储它的当前内部状态,也可以使用备忘录来恢复其内部状态。
Mementor(备忘录):存储原发器的内部状态,备忘录的设计一般可以参考原发器的设计,根据实际需要确定备忘录类中的属性。
Caretaker(负责人):负责人又称为管理者,在负责人类中可以存储一个或多个备忘录对象,它只负责存储对象,而不能修改对象,也无须知道对象的实现细节
Memento模式基本代码
原发器类
class Originator{
private string state;
public string State
{
get{
return state;}
set{
state=value;}
}
public Mementor CreateMemento()//创建备忘录存储它当前的内部状态
{
return (new Menmento(state));
}
public void SetMementor(Memento memento)//使用备忘录恢复
{
state=memento.State;
}
public void Show()
{
Console.WriteLine("State="+state);
}
备忘录类
class Memento
{
private string state;//体现参考原发器设计
public Memento(string state)
{
this.state=state;
}
public string State
{
get{
return state;}
}
}
管理者类
class Caretaker
{
private Memento memento;
public Memento Memento
{
get{
return memento;}
set{
memento=value;}
}
}
客户端类
class Program
{
static void Main(string[] args)
{
Origintor o=new Originator();
o.state="On";
o.Show();
Caretaker c=new Caretaker();
c.Mementor=o.CreateMemento();//保存备忘录
o.State="Off";
o.Show();
o.SetMemento(c.Memento);
o.Show();
Console.Read();
}
}
优点:
- 使用备忘录模式可以把复杂的发起人内部信息对其他的对象屏蔽起来,从而可以恰当保持封装的边界。
- 本模式简化了发起人类。发起人类不再需要管理和保存其内部状态的一个个版本,客户端可以自行管理他们所需要的这些状态的版本。
- 当发起人角色的状态改变的时候,有可能这个状态无效,这时候就可以使用暂时存储起来的备忘录将状态复原。
缺点:
- 如果发起人角色的状态需要完整地存储到备忘录对象中,那么在资源消耗上面备忘录对象会很大。
- 当管理者角色将一个备忘录存储起来的时候,管理者可能并不知道这个状态会占用多大的存储空间,从而无法提醒用户一个操作是否很大。
适用场合:
- 如果必须保存一个对象在某一个时刻的全部或者部分状态,方便在以后需要的时候,可以把该对象恢复到先前的状态,可以使用备忘录模式。
本质:保存和恢复内部状态
备忘录模式和原型模式
- 这两个模式可以组合使用
- 在原发器对象(发起人对象)创建备忘录对象的时候,如果原发器对象中全部或者大部分的状态都需要保存,一个简洁的方式就是直接克隆一个原发器对象。也就是说,这个时候备忘录对象里面存放的是一个原发器对象的实例。
练习实例-象棋悔棋