备忘录模式(Memento Pattern)
定义
又称为快照模式(Snapshot Pattern)或 Token 模式,是指在不破坏封闭的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可以将该对象恢复到原先保存的状态。
备忘录模式提供了一种状态恢复的实现机制,使得用户可以方便地回到一个特定的历史步骤。当新的状态无效或者存在问题时,可以使用暂时存储起来的备忘录将状态复原。
属于行为型模式。
适用场景
- 需要保存历史快照的场景
- 希望在对象之外保存状态,且除了自己其他类对象无法访问状态保存具体内容。
标准示例
- Originator(发起人):负责创建一个备忘录(Memento),用以记录当前时刻自身的内部状态,并可使用备忘录恢复内部状态。Originator可以根据需要决定Memento存储自己的哪些内部状态。
- Memento(备忘录):负责存储Originator对象的内部状态,并可以防止Originator以外的其他对象访问备忘录。备忘录有两个接口:Caretaker只能看到备忘录的窄接口,他只能将备忘录传递给其他对象;Originator却可看到备忘录的宽接口,允许它访问返回到先前状态所需要的所有数据。
- Caretaker(管理者):负责保存备忘录Memento,不能对Memento的内容进行访问或者操作。管理者类中可以存储一个或多个备忘录对象,它只负责存储对象,而不能修改对象(负责任类只提供备忘录对象的读写接口,不提供备忘录属性的读写接口),也无须知道对象的实现细节。
Originator
/**
* 发起人 —— 创建/访问备忘录
*/
@Data
public class Originator {
private String state;
private String id;
public Originator(String state,String id){
this.state = state;
this.id = id;
}
public Memento saveMemento(){
return new Memento(this.state,this.id);
}
public void reloadFromMementoStack(Memento memento){
this.state = memento.getState();
this.id = memento.getId();
}
}
Memento
/**
* 备忘录
*/
@Data
public class Memento {
private String state;
private String id;
public Memento(String state,String id){
this.state = state;
this.id = id;
}
}
Caretaker
/**
* 管理者——存取备忘录
*/
public class Caretaker {
private final Stack<Memento> MEMENTO_STACK = new Stack<Memento>();
public Memento getMemento(){
Memento memento = MEMENTO_STACK.pop();
return memento;
}
public void addMemento(Memento memento){
MEMENTO_STACK.push(memento);
}
}
ClientTest
public class ClientTest {
public static void main(String[] args) {
Caretaker caretaker = new Caretaker();
Originator originator = new Originator("满血满蓝","2024-07-08 13:00:00");
Memento memento = originator.saveMemento();
caretaker.addMemento(memento);
System.out.println(".......game start......");
System.out.println("第一次存档:" + memento);
System.out.println();
originator = new Originator("半血半蓝","2024-07-08 14:00:00");
memento = originator.saveMemento();
caretaker.addMemento(memento);
System.out.println(".......game half time......");
System.out.println("第二次存档:" + memento);
System.out.println();
System.out.println(".......game over......");
System.out.println("0血0蓝 2024-07-08 15:00:00");
System.out.println();
System.out.println(".......读取第二次存档......");
memento = caretaker.getMemento();
originator.reloadFromMementoStack(memento);
System.out.println(memento);
System.out.println();
System.out.println(".......读取第一次存档......");
memento = caretaker.getMemento();
originator.reloadFromMementoStack(memento);
System.out.println(memento);
}
}
执行客户端后输出结果为:
.......game start......
第一次存档:Memento(state=满血满蓝, id=2024-07-08 13:00:00)
.......game half time......
第二次存档:Memento(state=半血半蓝, id=2024-07-08 14:00:00)
.......game over......
0血0蓝 2024-07-08 15:00:00
.......读取第二次存档......
Memento(state=半血半蓝, id=2024-07-08 14:00:00)
.......读取第一次存档......
Memento(state=满血满蓝, id=2024-07-08 13:00:00)
备忘录模式通常用于需要撤销操作或者回滚操作的场景,如:
- 文本编辑器:保存撤销和重做操作之前的文本状态。
- 游戏存档:保存游戏进度,并在玩家需要恢复游戏进度时可以使用。
- 事务管理:在数据库事务管理中,保存事务执行之前的状态,以便在需要回滚事务时可以恢复到之前的状态。
- 安全监管:记录系统的运行状态,以便在出现问题时可以回溯到之前的状态,找到问题所在。
以上就是备忘录模式的全部内容,感谢阅读。