模式简介
在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。
很多时候我们要记录一个对象的内部状态,为了允许用户撤销不确定的操作或从错误中恢复过来。同时,为了不违反封装的原则,而不能暴露其内部状态和实现。想象一下日常生活中我们经常会遇到重置密码的问题,假设账号密码在初始化后,保留一份备忘录以便今后重置时使用,同样的,我们不能将密码暴露给其它对象。这时,可以使用备忘录模式解决这个问题。
结构分析
UML类图
角色说明
- Memento
备忘录。存储原发器对象的内部状态,防止原发器以外的对象访问备忘录。
- Originator
原发器。提供一个方法创建备忘录,用以记录当前时刻它的内部状态,并提供一个使用备忘录恢复内部状态的方法。
- Caretaker
负责人。负责保存备忘录,不能对备忘录的内容进行操作或检查。
工作原理
管理器向原发器请求一个备忘录,保留一段时间,将其送回原发器。
结构代码
//备忘录public class Memento{ private string _state; public Memento(string state) { _state = state; } public string GetState() { return _state; }}//原发器public class Originator{ public string State { get; set; } public Memento CreateMemento() { return new Memento(State); } public void SetMemento(Memento memento) { Console.WriteLine("Restoring state..."); State = memento.GetState(); }}//负责人public class Caretaker{ public Memento Memento { get; set; }}//客户端调用class Program{ static void Main(string[] args) { Originator originator = new Originator(); originator.State = "Off"; Caretaker caretaker = new Caretaker(); caretaker.Memento = originator.CreateMemento(); originator.State = "On"; originator.SetMemento(caretaker.Memento); Console.WriteLine(originator.State); Console.ReadLine(); }}
程序输出:
示例分析
本节通过一个重置密码的示例来讲述备忘录模式,首先声明备忘录Memento。
public class Memento{ public string UserName { get; private set; } public string Password { get; private set; } public Memento(string userName,string password) { UserName = userName; Password = password; }}
声明原发器User,包含UserName和Password属性,提供CreateMemento方法创建备忘录,以及SetMemento方法提供重置功能。
public class User{ public string UserName { get; set; } public string Password { get; set; } public User(string username,string password) { this.UserName = username; this.Password = password; } public Memento CreateMemento() { return new Memento(UserName, Password); } public void SetMemento(Memento memento) { this.UserName = memento.UserName; this.Password = memento.Password; }}public class UserMemory{ public Memento Memento { get; set; }}
客户端调用,创建jack账号并创建备忘录,随后修改了两次密码,最后使用备忘录进行重置。
class Program{ static void Main(string[] args) { User jack = new User("jack", "12345"); UserMemory memory = new UserMemory(); memory.Memento = jack.CreateMemento(); jack.Password = "23456"; jack.Password = "qwert"; jack.SetMemento(memory.Memento); Console.WriteLine(jack.Password); Console.ReadLine(); }}
使用场景
必须保存某个对象在某一时刻的状态,以便以后需要时恢复到该状态。
不希望暴露对象的实现细节以至破坏对象的封装性。