模式动机
现在大多数软件都有撤销的功能,快捷键一般都是Ctrl+Z,即我们需要提供一种类似“后悔药”的机制,让软件可以回到之前的状态,因此需要保存用户每一次操作时系统的状态,一旦出现误操作,可以把存储的历史状态取出即可回到之前的状态。备忘录模式是一种给我们的软件提供后悔药的机制,通过它可以使系统恢复到某一特定的历史状态。
模式定义
在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样可以在以后将对象恢复到原先保存的状态。
模式结构
原发器:Originator,这是需要被保存的对象,同时负责创建备忘录以及恢复到之前状态
备忘录:Memento,负责存储原发器的内部状态
负责人:Caretaker,只负责保存好备忘录,它不能对备忘录里的内容进行操作
代码示例
假设我们有一个用户对象,有用户名和密码两个字段,当设置好用户名和密码之后,我们需要提供一个撤销操作。我们以此为例来演示备忘录模式。
//原发器,其实说白了就是需要被保存历史状态的对象
public class User {
private String name;
private String password;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Memento saveMemento(){
return new Memento(name,password);
}
public void restoreMemento(Memento memento){
this.name = memento.getName();
this.password = memento.getPassword();
}
}
//备忘录,实质上就是原发器的一个快照
public class Memento {
private String name;
private String password;
public Memento(String name,String password){
this.name = name;
this.password = password;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
/**
* 负责人,主要是负责保存备忘录,可以理解为用于放备忘录的一个容器,当需要还原到历史状态时,就从这里取出来
* 如果需要保存多个历史版本,这里就可以使用容器,把多个备忘录Memento对象放到一个容器里面
*
*/
public class Caretaker {
private Memento memento;
public Memento getMemento() {
return memento;
}
public void setMemento(Memento memento) {
this.memento = memento;
}
}
//客户端测试
public class Client {
public static void main(String[] args) {
User u = new User();
u.setName("张三");
u.setPassword("password_123");
Memento m = u.saveMemento();//创建用户的对象的一个备忘录
Caretaker c = new Caretaker();//创建负责人,用于保存备忘录
c.setMemento(m);//保存备忘录到Caretaker中
//重新设置用户名和密码
u.setName("张三_update");
u.setPassword("password_123_update");
//执行撤销操作,还原用户对象
u.restoreMemento(c.getMemento());
System.out.println(u.getName());//张三
System.out.println(u.getPassword());//password_123
}
}
总结
备忘录模式相对比较简单,主要包含三个角色:原发器用于创建一个备忘录,并存储它的当前内部状态,同时提供备忘录的保存和恢复方法;备忘录存储原发器的内部状态,根据原发器来决定保存哪些内部状态;负责人负责只保存备忘录,不能对备忘录的内容进行操作或检查。
忘录模式的主要优点在于提供了一种状态恢复的机制,使得用户可以方便地回到一个特定的历史状态,而且可以通过在负责人中定义集合对象来存储多个备忘录,达到保存原发器的多个历史状态的效果;备忘录模式的主要缺点在于资源消耗过大,因为每一个历史状态的保存都需要一个备忘录对象。