定义
在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样以后就可以将该对象恢复到原先保存的状态。
其核心就是保存某个对象内部状态的拷贝,这样以后就可以将该对象恢复到原先状态。
结构图
- Originator(发起人 ):负责创建一个备忘录Memento,用于记录当前时刻它的内部状态,并可使用备忘录恢复内部状态。Originator可以根据需要决定Memento存储Originator的那些内部状态。
- Memento(备忘录):负责存储Originator的内部状态,并可防止Originator以外的其他对象访问备忘录Memento。备忘录有两个接口,Caretaker只能看到Memento的窄接口,它只能将备忘录传递给其他对象。Originator可以看到一个宽接口,允许它访问返回到原先状态的所有数据。
- Caretaker(管理者):负责保存好备忘录Memento,不能对备忘录的内容进行操作或者检查。
场景
- 录入大批量人员资料。正在录入当前人员资料时,发现上一个人员资料录入有误,此时要恢复上一个人的资料,再进行修改。
- Word文档编辑时,电脑突然死机或断电,再打开时,word提示是否恢复到原有文档。
- 管理系统中,公文撤回功能。
- 棋类游戏中的悔棋。
- 普通软件中的撤销操作。
- 数据库软件中事务管理的回滚操作。
- Photoshop软件中的历史记录。
模拟案例
备忘录保存员工信息
- 发起人类Employee
/**
* User:tumbler
* Desc:备忘录模式--源发器类
*/
public class Employee {
private String name;
private int age;
private int salary;
public Employee(String name, int age, int salary) {
this.name = name;
this.age = age;
this.salary = salary;
}
/**
* 备忘录,进行备忘操作。
* @return
*/
public Memento memento() {
return new Memento(this);
}
/**
* 恢复备忘录内容
* @param memento
*/
public void recovery(Memento memento) {
this.name = memento.getName();
this.age = memento.getAge();
this.salary = memento.getSalary();
}
//getter()、setter()
}
- 备忘录Memento
/**
* User:tumbler
* Desc:备忘录模式--备忘录类
*/
public class Memento {
private String name;
private int age;
private int salary;
/**
* 传入源发器类对象,将内部状态保存
* @param employee
*/
public Memento(Employee employee) {
this.name = employee.getName();
this.age = employee.getAge();
this.salary = employee.getSalary();
}
//getter()、setter()
}
- 负责人类Caretaker
/**
* User:tumbler
* Desc:备忘录模式--负责人类,管理备忘录对象
*/
public class Caretaker {
private Memento memento;
//可通过容器保存多个备忘点
//private List<Memento> list = new ArrayList<>();
public Memento getMemento() {
return memento;
}
public void setMemento(Memento memento) {
this.memento = memento;
}
}
- 测试Client
/**
* User:tumbler
* Desc:备忘录模式--测试
*/
public class Client {
public static void main(String[] args) {
Caretaker caretaker = new Caretaker();
Employee employee = new Employee("tumbler", 23, 8000);
System.out.println("第一次打印对象:"+ employee.getName() + "---" + employee.getAge() + "---" + employee.getSalary());
//备忘一次
caretaker.setMemento(employee.memento());
employee.setName("不倒翁");
employee.setAge(23);
employee.setSalary(10000);
System.out.println("第二次打印对象:"+ employee.getName() + "---" + employee.getAge() + "---" + employee.getSalary());
//恢复对象
employee.recovery(caretaker.getMemento());
System.out.println("第三次打印对象:"+ employee.getName() + "---" + employee.getAge() + "---" + employee.getSalary());
}
}
运行结果:
第一次打印对象:tumbler---23---8000
第二次打印对象:不倒翁---23---10000
第三次打印对象:tumbler---23---8000
- UML图
- 备忘点较多时,将备忘录圧栈, 或者将备忘录进行序列化和持久化。
public class Caretaker {
private Memento memento;
//可通过容器保存多个备忘点
//private List<Memento> list = new ArrayList<>();
//可通过圧栈
//private Stack<Memento> mementos = new Stack<>();
}