备忘录(Memento):在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象回复到原先保存的状态。
备忘录模式的结构图
备忘录模式中的角色:
- Originator:发起人类,负责创建一个备忘录 Memento,用以记录当前时刻它的内部状态,并可使用备忘录恢复内部状态。
- Memento:备忘录类,负责存储 Originator 对象的内部状态,并可防止 Originator 以外的其他对象访问备忘录 Memento。
- Caretaker:管理者类,负责保存好备忘录 Memento。
备忘录模式的具体实现
(1)发起人类
public class Originator {
private String state;
public void setState(String state) {
this.state = state;
}
public String getState() {
return state;
}
public Memento createMemento() {
return new Memento(state);
}
public void setMemento(Memento memento) {
state = memento.getState();
}
public void show() {
System.out.println("State = " + state);
}
}
(2)备忘录类
public class Memento {
private String state;
public Memento(String state) {
this.state = state;
}
public String getState() {
return state;
}
}
(3)管理者类
public class Caretaker {
private Memento memento;
public Memento getMemento() {
return memento;
}
public void setMemento(Memento memento) {
this.memento = memento;
}
}
(4)客户端调用
public class Client {
public static void main(String[] args) {
Originator originator = new Originator();
originator.setState("On");
originator.show();
Caretaker caretaker = new Caretaker();
caretaker.setMemento(originator.createMemento());
originator.setState("Off");
originator.show();
originator.setMemento(caretaker.getMemento());
originator.show();
}
}
(5)输出
State = On
State = Off
State = On
备忘录模式的使用场景
使用场景:
备忘录模式比较适用于功能比较复杂的,但需要维护或记录属性历史的类。
需要保存的属性只是众多属性中的一小部分,Originator 可以根据保存的 Memento 信息还原到前一状态。
备忘录模式的优缺点
优点:
有时一些发起人对象的内部信息必须保存在发起人对象以外的地方,但是必须要由发起人对象自己读取,这时,使用备忘录模式可以把复杂的发起人内部信息对其他的对象屏蔽起来,从而可以恰当地保持封装的边界。
本模式简化了发起人类。发起人不再需要管理和保存其内部状态的一个个版本,客户端可以自行管理他们所需要的这些状态的版本。
当发起人角色的状态改变的时候,有可能这个状态无效,这时候就可以使用暂时存储起来的备忘录将状态复原。
缺点:
如果发起人角色的状态需要完整地存储到备忘录对象中,那么在资源消耗上面备忘录对象会很昂贵。
当负责人角色将一个备忘录存储起来的时候,负责人可能并不知道这个状态会占用多大的存储空间,从而无法提醒用户一个操作是否很昂贵。
当发起人角色的状态改变的时候,有可能这个协议无效。如果状态改变的成功率不高的话,不如采取“假如”协议模式。