备忘录模式提供了一种状态恢复的实现机制,使得用户可以方便地回到一个特定的历史步骤,当新的状态无效或者存在问题时,可以使用暂时存储起来的备忘录将状态复原,比如喜欢下棋的同学,都知道撤销操作,就使用了备忘录模式。Windows上经典的空当接龙这个游戏,也提供了撤销操作,也是备忘录模式的一种。
Memento模式也叫备忘录模式,是行为模式之一,它的作用是在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样可以在以后将对象恢复到原先保存的状态。它是一种对象行为型模式,其别名为Token。
如果一个对象需要保存状态并可通过undo或rollback等操作恢复到以前的状态时,可以使用Memento模式。
1)一个类需要保存它的对象的状态(相当于Originator角色)
2)设计一个类,该类只是用来保存上述对象的状态(相当于Memento角色)
3)需要的时候,Caretaker角色要求Originator返回一个Memento并加以保存
4)undo或rollback操作时,通过Caretaker保存的Memento恢复Originator对象的状态
Originator:原生者,需要被保存状态以便恢复的那个对象。
Memento:备忘录,该对象由Originator创建,主要用来保存Originator的内部状态。
Caretaker:管理者,负责在适当的时间保存/恢复Originator对象的状态。
首先看看实体对象,我们假设是一个学生对象,存放在数据库中的对象,表示如下:
public class Person {
//姓名
private String name;
//性别
private String sex;
//年龄
private int age;
public Person() {
}
public Person(String name, String sex, int age) {
this.name = name;
this.sex = sex;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
//备份
public Memento createMemento() {
return new Memento(name, sex, age);
}
//恢复
public void setMemento(Memento memento) {
this.name = memento.getName();
this.sex = memento.getSex();
this.age = memento.getAge();
}
@Override
public String toString() {
return "Person [name=" + name + ", sex=" + sex + ", age=" + age + "]";
}
}
public class Caretaker {
private Memento memento;
public Caretaker(Memento memento) {
this.memento = memento;
}
public Memento getMemento() {
return memento;
}
public void setMemento(Memento memento) {
this.memento = memento;
}
}
public class Memento {
private String name;
private String sex;
private int age;
public Memento(String name, String sex, int age) {
this.name = name;
this.sex = sex;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
我们给出一个测试类,如下:
public class MainClass {
public static void main(String[] args) {
// 初始化
Person person = new Person("张三", "男", 30);
System.out.println(person.toString());
// 创建一个管理者
Caretaker care = new Caretaker(person.createMemento());
// 重新设置person的值
person.setName("小丽");
person.setSex("女");
person.setAge(20);
System.out.println(person);
// 恢复
person.setMemento(care.getMemento());
System.out.println(person);
}
}
Person [name=张三, sex=男, age=30]
Person [name=小丽, sex=女, age=20]
Person [name=张三, sex=男, age=30]
本模式简化了发起人类。发起人不再需要管理和保存其内部状态的一个个版本,客户端可以自行管理他们所需要的这些状态的版本。存储也是需要一定空间的,如果存储的空间很大,就会很浪费资源,对于有些程序或者设备来讲,存储的成本会很高。
备忘录对象是一个用来存储另外一个对象内部状态的快照的对象。备忘录模式的用意是在不破坏封装的条件下,将一个对象的状态捉住,并外部化,存储起来,从而可以在将来合适的时候把这个对象还原到存储起来的状态。