1.定义
Without violating encapsulation,capture and externalize an object's internal state so that the object can be restored to this state later.(在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之处保存这个状态。这样以后就可将该对象恢复到原先保持的状态)
Originator发起人角色:记录当前时刻的内部状态,负责定义哪些属于备份范围的状态,负责创建和恢复备份数据。
Memento备忘录角色:负责存储Originator发起人对象的内部状态,在需要的时候提供发起人需要的内部状态。
Caretaker备忘录管理员角色:对备忘录进行管理、保存和提供备忘录。
2.代码实现
/// <summary> /// 发起人角色 /// </summary> public class Originator { private string _state; public void SetState(string state) { _state = state; } public string GetState() { return _state; } public Memento CreateMemento() { return new Memento(_state); } public void RestoreMemento(Memento memento) { this._state = memento.GetState(); } }
/// <summary> /// 备忘录角色 /// </summary> public class Memento { private string _state; public Memento(string state) { _state = state; } public void SetState(string state) { _state = state; } public string GetState() { return _state; } }
/// <summary> /// 备忘录管理员 /// </summary> public class CareTaker { private Memento _memento; public void SetMemento(Memento memento) { _memento = memento; } public Memento GetMemento() { return _memento; } }
/// <summary> /// 场景类 /// </summary> class Program { private static void Main(string[] args) { Originator originator = new Originator(); CareTaker careTaker = new CareTaker(); careTaker.SetMemento(originator.CreateMemento()); originator.RestoreMemento(careTaker.GetMemento()); Console.ReadKey(); } }
3.更好的封装
备份是不能被修改的,也就是说需要缩小备份出的备忘录的阅读权限,保证只能是发起人可读就成了,那怎么才能做到这一点呢?使用内置类。
/// <summary> /// 发起人角色 /// </summary> public class Originator : ICloneable { private string _state; public void SetState(string state) { _state = state; } public string GetState() { return _state; } public IMemento CreateMemento() { return new Memento(_state); } public void RestoreMemento(IMemento memento) { this._state = ((Memento) memento).GetState(); } public object Clone() { return MemberwiseClone(); } /// <summary> /// 备忘录角色,全是Private访问权限,也就是说除了发起人之外,其他用户无法访问备忘录的数据。通过接口关联给其他类使用。 /// </summary> private class Memento : IMemento { private string _state; public Memento(string state) { _state = state; } public void SetState(string state) { _state = state; } public string GetState() { return _state; } } }
/// <summary> /// 备忘录角色 /// </summary> public interface IMemento { }
/// <summary> /// 备忘录管理员 /// </summary> public class CareTaker { private IMemento _memento; public void SetMemento(IMemento memento) { _memento = memento; } public IMemento GetMemento() { return _memento; } }
4.备忘录模式的扩展
(1)clone方式的备忘录
/// <summary>
/// 发起人兼备忘录角色
/// </summary>
public class Originator : ICloneable
{
private string _state;
private Originator _backUp;
public void SetState(string state)
{
_state = state;
}
public string GetState()
{
return _state;
}
public void CreateMemento()
{
_backUp = (Originator)Clone();
}
public void RestoreMemento()
{
this._state = _backUp.GetState();
}
public object Clone()
{
return MemberwiseClone();
}
}
/// <summary>
/// 场景类
/// </summary>
class Program
{
private static void Main(string[] args)
{
Originator originator = new Originator();
originator.SetState("hello");
Console.WriteLine(originator.GetState());
originator.CreateMemento();
originator.SetState("hello GG");
Console.WriteLine(originator.GetState());
originator.RestoreMemento();
Console.WriteLine(originator.GetState());
Console.ReadKey();
}
}
(2)多备份的备忘录
/// <summary> /// 备忘录管理员 /// </summary> public class CareTaker { private readonly List<KeyValuePair<string, Memento>> _mementos = new List<KeyValuePair<string, Memento>>(); public void SetMemento(string idx, Memento memento) { _mementos.Add(new KeyValuePair<string, Memento>(idx, memento)); } public Memento GetMemento(string idx) { KeyValuePair<string, Memento> mementoKv = _mementos.FirstOrDefault(item => item.Key.Equals(idx)); return mementoKv.Value; } }
浙公网安备 33010602011771号