Memento(备忘录) 行为型 对象 1
Intent_意图2
在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态
Motivation_动机3
备忘录对象是一个用来存储另一个对象内部状态的快照的对象。备忘录模式的用意是在不破坏封装的条件下,将一个对象的状态捕捉住,并外部化,存储起来,从而可以在将来合适的时候把这个对象还原到存储起来的状态。备忘录模式常常与命令模式和迭代子模式一同使用
Applicability_适用性4
为了允许用户取消不确定或错误的操作,将对象的内部状态记录下来,当需要的时候,能恢复到对象原先的状态
Structure_结构5
Participants_参与者6
- Originator(发起人) 记录当前时刻的状态,负责定义哪些属于需要备份的状态,负责创建和恢复备忘录数据
- Memento(备忘录) 负责存储发起人的状态
- Caretaker(备忘录管理员) 对备忘录进行管理和保存
Collaborations_协作7
- Memento将Originator对象的内部状态存储起来
-> Memento可以根据Originator对象的判断来决定存储多少Originator对象的内部状态。
-> Memento可以保护其内容不被Originator对象之外的任何对象所读取
-> Memento有两个等效接口:
-> narrow(窄接口):Caretaker对象(和其他除Originator对象之外的任何对象)看到的是Memento的narrow interface(窄接口),narrow只允许把Memeto对象传给其他的对象
-> wide(宽接口):与narrow相反,Originator对象可以看到一个wide interface(宽接口),wide允许它读取所有的数据,以便根据这些数恢复Originator对象的内部状态 - Originator负责创建一个含有当前内部状态的Memento对象,并使用Memento对象来存储其内部状态
- Caretaker负责保存Memento对象,不检查Memento对象的内容
Comsequences_结果8
- 优点
将被储存的状态放在外面,不要和关键对象混在一起,可以帮助维护内聚
保持关键对象的数据封装
提供了容易实现的恢复能力 - 缺点
当成员变量过多,储存和恢复状态的过程可能相当耗时 - 用途
需要保存/恢复数据的相关状态场景
提供一个可回滚的操作
Implementation/Sample Code_实现/范例代码910
Implementation
Memento
public class Memento {
private String state;
public Memento(String state) {
this.state = state;
}
public void setState(String state) {
this.state = state;
}
public String getState() {
return state;
}
}
Originator
public class Originator {
private String state;
public Memento createMemento() {
return new Memento(state);
}
public void restoreMemento(Memento memento) {
this.state = memento.getState();
}
public void setState(String state) {
this.state = state;
System.out.println("Current state: " + this.state);
}
public String getState() {
return state;
}
}
Caretaker
public class Caretaker {
public Memento memento;
public Memento retrieveMemento() {
return memento;
}
public void saveMemento(Memento memento) {
this.memento = memento;
}
}
Sample Code
Client
public class Client {
public static void main(String[] args) {
Originator originator = new Originator();
Caretaker caretaker = new Caretaker();
// change Originator's state
originator.setState("On");
// create Memento, and save Originator's state
caretaker.saveMemento(originator.createMemento());
// change Originator's state
originator.setState("Off");
// restore Originator's state
originator.restoreMemento(caretaker.retrieveMemento());
System.out.println(originator.getState());
}
}
Result
Current state: On
Current state: Off
On
Known Uses_已知应用11
Related Patterns_相关模式12
“白盒”备忘录:Memento对任何对象都提供一个接口,即宽接口,Memento的内部所存储的状态对所有对象公开
“黑盒”备忘录:Memento对Originator提供一个宽接口,而为其他对象提供一个窄接口,将Memento设计成Originator类的内部类,从而将Memento对象封装在Originator里面,在外部提供一个标识接口给Caretaker以及其他对象。这样,Originator类看到的是Memento的所有接口,而Caretaker以及其他对象仅能看到标识接口MementoIF所暴露出来的接口
模式分类归属 ↩︎
意图:描述该模式的作用,以及该模式的定义 ↩︎
动机:给出了问题以及如何解决这个问题的具体场景 ↩︎
适用性:描述模式可以被应用在什么场合 ↩︎
结构:提供了图示,显示出参与此模式的类之间的关系 ↩︎
参与者:描述在此设计中所涉及到的类和对象在模式中的责任和角色 ↩︎
协作 :告诉参与者如何在此模式中合作 ↩︎
结果:描述采用此模式之后可能产生的效果,好的与不好的 ↩︎
实现:提供了在实现该模式时需要使用的技巧,以及应该小心面对的问题 ↩︎
范例代码:提供代码的片段 ↩︎
已知应用:用来描述已经在真实系统中发现的模式例子 ↩︎
相关模式:描述了此模式和其他模式之间的关系 ↩︎