备忘录模式
    备忘录模式,即保存某个对象内部状态的拷贝,这样以后就可以将该对象恢复到原先的状态。
场景
    当我们使用文本编译器记录一些内容时,发现这一步写错了,往往可以使用Ctrl+Z的方式会退到上一个状态,其中运用到的知识就是备忘录模式。
模式结构
- 发起者角色(Originator):负责创建一个备忘录用以记录当前时刻它的内部状态,并可以使用备忘录恢复内部状态。
 
- 备忘录角色(Memento):负责存储Originator对象的内部状态,并可以防止Originator以外的其他对象访问备忘录。
 
- 管理者角色(CareTake):负责保存好备忘录。
 
代码
备忘录角色
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
   | package designMode.Memento;
 
 
 
 
  public class EmpMemento {     private String name;     private int age;     private int salary;
      public EmpMemento(Emp emp) {         this.name = emp.getName();         this.age = emp.getAge();         this.salary = emp.getSalary();     }           }
   | 
 
发起者角色
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
   | public class Emp {     private String name;     private int age;     private int salary;
           public EmpMemento memento() {         return new EmpMemento(this);     }
           public void recovery(EmpMemento empMemento) {         this.name = empMemento.getName();         this.age = empMemento.getAge();         this.salary = empMemento.getSalary();     }           }
  | 
 
管理者角色
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
   | 
 
 
 
 
  public class CareTaker {     private EmpMemento memento;
      public EmpMemento getMemento() {         return memento;     }
      public void setMemento(EmpMemento memento) {         this.memento = memento;     } }
 
  | 
 
客户端
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
   | public class Client {     public static void main(String[] args) {         CareTaker careTaker = new CareTaker();
          Emp emp = new Emp("YoungDream", 20, 7800);         System.out.println("第一次打印==> " + emp);
          careTaker.setMemento(new EmpMemento(emp));
          emp.setAge(22);         emp.setSalary(8000);         System.out.println("第二次打印==> " + emp);
          emp.recovery(careTaker.getMemento());
          System.out.println("数据恢复后打印==> " + emp);
      } }
  | 
 
控制台
1 2 3
   | 第一次打印==> Emp{name='YoungDream', age=20, salary=7800} 第二次打印==> Emp{name='YoungDream', age=22, salary=8000} 数据恢复后打印==> Emp{name='YoungDream', age=20, salary=7800}
  | 
 
总结
优点
- 备忘录模式可以把发起者内部信息对象屏蔽起来,从而可以保持封装的边界。
 
- 简化了发起者类。当发起者角色的状态改变的时候,有可能这个状态无效,这时候就可以使用暂时存储起来的备忘录将状态复原。
 
缺点
- 如果状态需要完整地存储到备忘录对象中,那么在资源消耗上面备忘录对象比较昂贵。
 
- 当发起者对象的状态改变的时候,有可能这个协议无效。如果状态改变的成功率达不到要求,可以考虑采取“假如”协议模式。
 
当备份点较多时
- 设置栈将备忘点压栈
 
- 将多个备忘录对象持久化和序列化保存到本地
 
常见场景
- 数据库事务管理中的回滚操作
 
- 文本编辑器中的
Ctrl+z回退操作