GOF23设计模式之备忘录模式(memento)
一、备忘录模式概述
保存某个对象内部状态的拷贝,使得以后就可以将该对象恢复到原先的状态。
结构:
(1)源发器类 Originator
负责创建一个备忘录 Memento,用以记录当前时刻它的内部状态,并可使用备忘录恢复内部状态。
(2)备忘录类 Memento
负责存储 Originator 对象的内部状态,并可防止 Originator 以外的其他对象访问备忘录 Memento 。
(3)负责人类 CareTake
负责保存备忘录 Memento 。
二、备忘录模式示例代码
1 /** 2 * 备忘录类 3 * @author CL 4 * 5 */ 6 public class EmpMemento { 7 private String name; 8 private int age; 9 private double salary; 10 11 public EmpMemento(Employee emp) { 12 this.name = emp.getName(); 13 this.age = emp.getAge(); 14 this.salary = emp.getSalary(); 15 } 16 17 public String getName() { 18 return name; 19 } 20 21 public void setName(String name) { 22 this.name = name; 23 } 24 25 public int getAge() { 26 return age; 27 } 28 29 public void setAge(int age) { 30 this.age = age; 31 } 32 33 public double getSalary() { 34 return salary; 35 } 36 37 public void setSalary(double salary) { 38 this.salary = salary; 39 } 40 41 }
1 /** 2 * 源发器类 3 * @author CL 4 * 5 */ 6 public class Employee { 7 private String name; 8 private int age; 9 private double salary; 10 11 public Employee(String name, int age, double salary) { 12 this.name = name; 13 this.age = age; 14 this.salary = salary; 15 } 16 17 /** 18 * 进行备忘操作,并返回备忘录对象 19 * @return 20 */ 21 public EmpMemento memento() { 22 return new EmpMemento(this); 23 } 24 25 /** 26 * 进行数据恢复,恢复成指定备忘录对象的值 27 */ 28 public void recovery(EmpMemento emt) { 29 this.name = emt.getName(); 30 this.age = emt.getAge(); 31 this.salary = emt.getSalary(); 32 } 33 34 public String getName() { 35 return name; 36 } 37 38 public void setName(String name) { 39 this.name = name; 40 } 41 42 public int getAge() { 43 return age; 44 } 45 public void setAge(int age) { 46 this.age = age; 47 } 48 49 public double getSalary() { 50 return salary; 51 } 52 53 public void setSalary(double salary) { 54 this.salary = salary; 55 } 56 57 }
1 /** 2 * 负责人类 3 * @author CL 4 * 5 */ 6 public class CareTaker { 7 8 private EmpMemento memento; 9 10 //可以通过容器,增加多个备忘点 11 // private List<EmpMemento> list = new ArrayList<EmpMemento>(); 12 13 public EmpMemento getMemento() { 14 return memento; 15 } 16 17 public void setMemento(EmpMemento memento) { 18 this.memento = memento; 19 } 20 21 }
测试:
1 /** 2 * 测试备忘录模式 3 * @author CL 4 * 5 */ 6 public class Client { 7 8 public static void main(String[] args) { 9 CareTaker ct = new CareTaker(); 10 11 Employee emp = new Employee("曹磊", 23, 8000); 12 System.out.println("第一次打印对象:"+emp.getName()+"---"+emp.getAge() 13 +"---"+emp.getSalary()); 14 15 //备忘一次 16 ct.setMemento(emp.memento()); 17 18 //修改源发器类的值 19 emp.setName("Tom"); 20 emp.setAge(99); 21 emp.setSalary(123456); 22 23 System.out.println("第二次打印对象:"+emp.getName()+"---"+emp.getAge() 24 +"---"+emp.getSalary()); 25 26 //恢复到备忘录对象保存的状态 27 emp.recovery(ct.getMemento()); 28 29 System.out.println("第三次打印对象:"+emp.getName()+"---"+emp.getAge() 30 +"---"+emp.getSalary()); 31 32 } 33 }
控制台输出:
第一次打印对象:曹磊---23---8000.0 第二次打印对象:Tom---99---123456.0 第三次打印对象:曹磊---23---8000.0
注意:本例子中只设置了一个备忘点,当通过容器设置多个备忘点时,就可以实现 Word 中 Ctrl + Z 和 Ctrl + Y 的操作。
三、备忘录模式常见开发应用场景
(1)棋类游戏中的悔棋操作;
(2)Office 中的撤销、恢复功能;
(3)数据库软件中事务管理的回滚操作;
(4)Photoshop 软件中的历史记录;
(5)…………