备忘录模式
# 分类
行为型模式
# 定义
- 备忘录模式(Memento Pattern) 保存一个对象的某个状态,以便在适当的时候恢复对象的状态。
# 意图
在不破坏封装性的提前下,捕获一个对象的内部状态,并在该对象之外保存这个状态。
# 应用场景
- 需要
保存/恢复
数据的相关状态场景。 - 提供一个
可回滚
操作的场景。
实用案例
- 后悔药。
- 打游戏时的存档。
- Windows的Ctrl+Z。
- IE中的后退。
- 数据库的事务管理。
# 角色与结构图
- Originator:
发起人角色
负责创建一个备忘录Memento,用以记录当前时刻它的内部状态,并可使用备忘录恢复内部状态。Originator可根据需要决定Memento存储Originator的哪些内部状态。 - Memento:
备忘录角色
负责储存Originator对象的内部状态,并可防止 Originator 以外的其他对象访问备忘录Memento。备忘录有两个接口,Caretaker只能看到备忘录的窄接口,它只能将备忘录传递给其他对象。 Originator能够看到一个宽接口,允许它访问返回到先前状态所需的所有数据。 - Caretaker:
管理者角色
负责保存好备忘录Memento,不能对备忘录的内容进行操作或检查。
下图解释了备忘录模式中各角色的作用

# 示例代码
//发起者
class Originator {
private string state;
public string State{
get{return this.state;}
set{this.state = value;}
}
public Memento CreateMemento(){
return new Memento(this.state);
}
public void SetMemento(Menento memento){
state = memento.State;
}
public void Show(){
Console.WriteLine("State = "+ State);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//备忘录
class Memento{
private string state;
public Memento(string state){
this.state = state;
}
public string Stete{
get{ return this.state;}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
//管理者
class Caretaker{
private Memento memento;
public Memento Memento{
get{ return this.memento;}
set{ memento = value;}
}
}
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
//客户端
class Client{
public static void Main(string[] args) {
Originator o = new Originator();
o.state = "On";
o.Show();
Caretaker c = new Caretaker();
c.Memento = c.CreateMement();
O.State = "Off";
o.Show();
o.SetMemento(c.Memento);
o.Show();
Console.ReadLine();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 优点
- 给用户提供了一种可以恢复状态的机制,可以使用户能够比较方便地回到某个历史状态。
- 实现了
信息的封装
,使得用户不需要关心状态的保存细节
。
# 缺点
消耗资源
,如果类的成员变量过多,势必会占用比较大的资源,而且每一次保存都会消耗一定的内存。
# 小结
把要保存的细节封装在Memento中,这样需要更改保存的细节也不用影响客户端了。
备忘录模式比较适用于
功能比较复杂的
,但需要维护或记录属性历史
的类,或者需要保存的属性只是众多属性中的一小部分时,Originator可以根据保存的Memento信息还原到前一状态。如果在某个系统中使用命令模式时,需要实现
命令的撤销
功能,那么命令模式可以使用备忘录模式来存储可撤销操作的状态
。有时一些对象的内部信息必须保存在对象以外的地方,但是必须由对象自己读取,这时,使用备忘录可以把复杂的对象内部信息对其他的对象屏蔽起来,从而可以恰当地保存封装的边界。
备忘录模式的最大作用在于当角色的状态改变的时候,有可能这个状态无效,这时候就可以使用暂时存储起来的备忘录将状态复原。
主要解决?所谓备忘录模式就是在
不破坏封装的前提下
,捕获
一个对象的内部状态
,并在该对象之外保存这个状态
,这样可以在以后将对象恢复
到原先保存的状态
。何时使用?很多时候我们总是需要
记录一个对象的内部状态
,这样做的目的就是为了允许用户取消不确定或者错误的操作
,能够恢复到他原先的状态
,使得他有"后悔药"
可吃。如何解决?通过一个
备忘录类
专门存储对象状态。关键代码?客户不与
备忘录
类耦合,与备忘录管理类
耦合
# 一句话概括
存储系统某一时刻的状态,并在合适的时机将其恢复。
编辑 (opens new window)
上次更新: 2025/03/22, 13:47:44