(十九)备忘录模式
备忘录模式(Memento Pattern)指在不破坏封装性的前提下,捕获一个对象的内部状态,并在对象之外保存这个状态。类似于快照机制。
1,备忘录模式的设计原则
1,发起人(Originator):负责创建一个备忘录,记录自身需要保存的状态;
2,备忘录(Memento):用于存储Originator的内部状态,且可以防止Originator以外的对象进行访问;
3,备忘录管理员(Caretaker):负责备忘录的管理与创建。
2,简单案例
草稿箱的实现就是一个备忘录的形式,通过草稿箱你可以恢复之前编写的内容,甚至无限次恢复。其实有些场景我们还可以考虑使用数组的形式而非栈,这样我们就可以根据索引回退到指定版本了。
public class Editor {
private String title;
private String content;
private String img;
//get,set
// 保存功能,实际是保存到备忘录
public ArticleMemento saveToMemento() {
ArticleMemento articleMemento = new ArticleMemento(this.title, this.content, this.img);
return articleMemento;
}
// 撤销功能就是从栈中取出上一个ArticleMemento对象
public void undoFromMemento(ArticleMemento articleMemento) {
this.title = articleMemento.getTitle();
this.content = articleMemento.getContent();
this.img = articleMemento.getImg();
}
//全参构造
//重写tosting
}
public class ArticleMemento {
private String title;
private String content;
private String img;
public String getTitle() {
return title;
}
public String getContent() {
return content;
}
public String getImg() {
return img;
}
//全参构造
//重写tosting
}
public class DraftBox {
private final Stack<ArticleMemento> STACK = new Stack<>();
public ArticleMemento getMemento() {
ArticleMemento articleMemento = null;
// 业务场景一:草稿实时保存,所以撤销指的是回滚到上一版本,并不是上一步。
// 第一次弹栈是当前对象,第二次弹栈是上一个对象。
// articleMemento = STACK.pop();
// articleMemento = STACK.pop();
// 业务场景二:及时撤销,用户在不保存的情况下撤销,即回退到上一步。
articleMemento = STACK.pop();
return articleMemento;
}
public void addMemento(ArticleMemento articleMemento) {
STACK.push(articleMemento);
}
}
public class Client {
public static void main(String[] args) {
DraftBox draftBox = new DraftBox();
Editor editor = new Editor("标题1", "备忘录模式", "abc.img");
ArticleMemento articleMemento = editor.saveToMemento();
draftBox.addMemento(articleMemento);
System.out.println(editor.getTitle()+"\t"+editor.getContent()+"\t"+editor.getImg());
System.out.println("修改标题");
editor.setTitle("标题2");
System.out.println("发生了修改后");
// 业务场景一:修改后并保存
/* articleMemento = editor.saveToMemento();
draftBox.addMemento(articleMemento);*/
System.out.println(editor.getTitle()+"\t"+editor.getContent()+"\t"+editor.getImg());
// 测试业务场景一
articleMemento = draftBox.getMemento();
editor.undoFromMemento(articleMemento);
System.out.println("执行撤销指令后");
System.out.println(editor.getTitle()+"\t"+editor.getContent()+"\t"+editor.getImg());
}
}
3,备忘录模式的点评
备忘录模式非常适用于需要回滚的业务场景,但是可以看到Memento中需要维护一份操作对象的成员变量,容易造成系统复杂。