前言

正文

介绍

在不破坏封装性的前提下,捕获一个对象的内部状态,并在对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态

我认为备忘只是用来辅助业务逻辑,这里可以按照职责,分为三个角色:

  • 备忘录角色:存储需要“备忘”的属性
  • 组织角色:进行业务逻辑的角色,也就是被“备忘”的角色
  • 管理备忘录角色:进行对备忘录的保存和提供

备忘录角色是为了不破坏封装性而存在的。对于备忘的状态,应该不可以修改其中的属性,如果不和组织角色分离,是可以通过暴露的 setter 进行状态的修改。而管理备忘录角色,是可以不和组织角色分离的

模板

类图

备忘录模式 - 图1

代码

被“备忘”的角色

  1. package cn.zjm404.stu.design.behavior.memento;
  2. import lombok.Getter;
  3. import lombok.Setter;
  4. @Getter
  5. @Setter
  6. public class Originator {
  7. private int id;
  8. private String msg;
  9. public Memento createMemento(){
  10. return new Memento(id,msg);
  11. }
  12. public void restoreMemento(Memento memento){
  13. this.id = memento.getId();
  14. this.msg = memento.getMsg();
  15. }
  16. }

存储备忘信息的角色

  1. package cn.zjm404.stu.design.behavior.memento;
  2. import lombok.AllArgsConstructor;
  3. import lombok.Getter;
  4. @AllArgsConstructor
  5. @Getter
  6. public class Memento {
  7. private int id;
  8. private String msg;
  9. }

管理备忘的角色

  1. package cn.zjm404.stu.design.behavior.memento;
  2. import java.util.Stack;
  3. public class Caretaker {
  4. private Stack<Memento> mementos;
  5. public Caretaker(){
  6. mementos = new Stack<>();
  7. }
  8. public void addMemento(Memento memento){
  9. mementos.push(memento);
  10. }
  11. public Memento getMemento(){
  12. return mementos.pop();
  13. }
  14. }

测试

  1. package cn.zjm404.stu.design.behavior.memento;
  2. public class Client {
  3. public static void main(String[] args) {
  4. Originator originator = new Originator();
  5. Caretaker caretaker = new Caretaker();
  6. originator.setId(1);
  7. originator.setMsg("hello world");
  8. //添加快照 m1
  9. Memento m1 = originator.createMemento();
  10. caretaker.addMemento(m1);
  11. //修改值
  12. originator.setMsg("HELLO WORLD");
  13. //添加快照 m2
  14. Memento m2 = originator.createMemento();
  15. caretaker.addMemento(m2);
  16. //修改
  17. originator.setMsg("hello");
  18. //恢复到快照 m2
  19. originator.restoreMemento(caretaker.getMemento());
  20. //输出信息
  21. System.out.println(originator.getId());
  22. System.out.println(originator.getMsg());
  23. }
  24. }