一、模式简介
定义:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便以后当需要时能将该对象恢复到原先保存的状态
场景:需要保存与恢复数据的场景,如玩游戏时中间结果的存档功能。需要提供一个可回滚操作的场景,如数据库事务的操作。
- 角色结构:
- 发起人(Originator)角色:记录当前时刻的内部状态信息,提供创建备忘录和恢复备忘录数据的功能,实现其他业务功能,它可以访问备忘录里的所有信息。
- 备忘录(Memento)角色:负责存储发起人的内部状态,在需要的时候提供这些内部状态给发起人。
- 管理者(Caretaker)角色:对备忘录进行管理,提供保存与获取备忘录的功能,但其不能对备忘录的内容进行访问与修改。
二、模式实现
public class Originator { -> 发起者
private String state;
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public Memento create(){
return new Memento(getState());
}
public void CtrlZ(Memento memento){
this.setState(memento.getState());
}
public void CtrlY(Memento memento){
this.setState(memento.getState());
}
}
public class Memento implements Cloneable{ -> 备忘录
private String state;
private Memento next;
public Memento(String state) {
this.state = state;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public Memento getNext() {
return next;
}
public void setNext(Memento next) {
this.next = next;
}
}
public class Caretaker { -> 管理者
private Memento mementoZ;
private Memento mementoY;
public Memento getMementoZ() {
if (mementoZ != null) {
Memento get = mementoZ;
mementoZ = mementoZ.getNext();
get.setNext(null);
return get;
}
return null;
}
public void setMementoZ(Memento mementoZ) {
if (this.mementoZ != null){
mementoZ.setNext(this.mementoZ);
}
this.mementoZ = mementoZ;
}
public Memento getMementoY() {
if (mementoY != null) {
Memento get = mementoY;
mementoY = mementoY.getNext();
get.setNext(null);
return get;
}
return null;
}
public void setMementoY(Memento mementoY) {
if (this.mementoY != null){
mementoY.setNext(this.mementoY);
}
this.mementoY = mementoY;
}
public void displayY() {
display(mementoY);
}
public void displayZ() {
display(mementoZ);
}
private void display(Memento memento) {
if (memento != null) {
System.out.println(memento.getState());
if (memento.getNext() != null) display(memento.getNext());
}
}
}
以编辑记事本为例子,编辑过程可以先后退到某一时间的进度,再重新前进到某一时间的进度,管理者包含了两个备忘录,分别是后退(组合键:Ctrl + Z)和前进(组合键:Ctrl + Y),发起人通过管理者获取到备忘录,轻松回到某一时间的进度。
Originator originator = new Originator();
Caretaker caretaker = new Caretaker();
originator.setState("s1");
caretaker.setMementoZ(originator.create());
originator.setState("s2");
caretaker.setMementoZ(originator.create());
originator.setState("s3");
System.out.println("当前状态:"+originator.getState());
caretaker.setMementoY(originator.create());
originator.CtrlZ(caretaker.getMementoZ());
System.out.println("当前状态:"+originator.getState());
caretaker.setMementoY(originator.create());
originator.CtrlZ(caretaker.getMementoZ());
System.out.println("当前状态:"+originator.getState());
caretaker.setMementoZ(originator.create());
originator.CtrlY(caretaker.getMementoY());
System.out.println("当前状态:"+originator.getState());
caretaker.setMementoZ(originator.create());
originator.CtrlY(caretaker.getMementoY());
System.out.println("当前状态:"+originator.getState());