一、备忘录模式定义
1.备忘录模式又称为快照模式或令牌模式,是指在不破坏封装的前提下,捕获一个对象的内部状态,并在对象之外保存这个状态。这样以后就可以将该对象恢复到原先保存的状态,属于行为型模式
2.在软件系统中,备忘录模式可以为我们提供一种”后悔药“机制,它通过存储系统各个历史状态的快照,使得我们可以在任一时刻将系统回滚到某一个历史状态
3.备忘录模式本质是从发起人实体类隔离存储功能,降低实体类职责。同时由于存储信息独立,且存储信息的实体交由管理类管理,则可以通过为管理类扩展额外的功能对存储信息进行扩展操作
4.备忘录模式的应用场景:
A.需要保存历史快照的场景
B.希望在对象之外保存状态,且除了自己其他类对象无法访问状态保存具体内容
二、备忘录模式示例
1.备忘录模式一般包含三种角色:
A.发起人角色(Originator):负责创建一个备忘录,记录自身需要保存的状态;具备状态回滚功能
B.备忘录角色(Memento):用于存储Originator的状态,且可以防止Originator以外的对象进行访问
C.备忘录管理员角色(Caretaker):负责存储、提供管理备忘录,无法对备忘录内容进行操作和访问
2.代码示例
1 /** 2 * 发起人角色 3 */ 4 public class Editor { 5 6 private String title; 7 private String content; 8 private String imgs; 9 10 public Editor(String title, String content, String imgs) { 11 this.title = title; 12 this.content = content; 13 this.imgs = imgs; 14 } 15 16 public String getTitle() { 17 return title; 18 } 19 20 public String getContent() { 21 return content; 22 } 23 24 public String getImgs() { 25 return imgs; 26 } 27 28 public void setTitle(String title) { 29 this.title = title; 30 } 31 32 public void setContent(String content) { 33 this.content = content; 34 } 35 36 public void setImgs(String imgs) { 37 this.imgs = imgs; 38 } 39 40 public ArticleMemento saveToMemento(){ 41 ArticleMemento articleMemento = new ArticleMemento(this.title,this.content,this.imgs); 42 return articleMemento; 43 } 44 45 public void undoFromMemento(ArticleMemento articleMemento){ 46 this.title = articleMemento.getTitle(); 47 this.content = articleMemento.getContent(); 48 this.imgs = articleMemento.getImgs(); 49 } 50 51 @Override 52 public String toString() { 53 return "Editor{" + 54 "title=‘" + title + ‘\‘‘ + 55 ", content=‘" + content + ‘\‘‘ + 56 ", imgs=‘" + imgs + ‘\‘‘ + 57 ‘}‘; 58 } 59 } 60 61 /** 62 * 备忘录角色 63 */ 64 public class ArticleMemento { 65 private String title; 66 private String content; 67 private String imgs; 68 69 public ArticleMemento(String title, String content, String imgs) { 70 this.title = title; 71 this.content = content; 72 this.imgs = imgs; 73 } 74 75 public String getTitle() { 76 return title; 77 } 78 79 public String getContent() { 80 return content; 81 } 82 83 public String getImgs() { 84 return imgs; 85 } 86 87 @Override 88 public String toString() { 89 return "ArticleMemento{" + 90 "title=‘" + title + ‘\‘‘ + 91 ", content=‘" + content + ‘\‘‘ + 92 ", imgs=‘" + imgs + ‘\‘‘ + 93 ‘}‘; 94 } 95 } 96 97 /** 98 * 备忘录管理角色 99 */ 100 public class DraftsBox { 101 private final Stack<ArticleMemento> STACK = new Stack<ArticleMemento>(); 102 103 public ArticleMemento getMemento(){ 104 ArticleMemento articleMemento = STACK.pop(); 105 return articleMemento; 106 } 107 108 public void addMemento(ArticleMemento articleMemento){ 109 STACK.push(articleMemento); 110 } 111 112 } 113 114 public class Test { 115 public static void main(String[] args) { 116 DraftsBox draftsBox = new DraftsBox(); 117 118 Editor editor = new Editor("我是这样手写Spring的,麻雀虽小五脏俱全", 119 "本文节选自《Spring5核心原理与30个类手写实战》一书,Tom著,电子工业出版社出版。", 120 "35576a9ef6fc407aa088eb8280fb1d9d.png"); 121 122 ArticleMemento articleMemento = editor.saveToMemento(); 123 draftsBox.addMemento(articleMemento); 124 125 System.out.println("标题:" + editor.getTitle() + "\n" + 126 "内容:" + editor.getContent() + "\n" + 127 "插图:" + editor.getImgs() + "\n暂存成功"); 128 129 System.out.println("完整的信息" + editor); 130 131 132 System.out.println("==========首次修改文章==========="); 133 editor.setTitle("【Tom原创】我是这样手写Spring的,麻雀虽小五脏俱全"); 134 editor.setContent("本文节选自《Spring5核心原理与30个类手写实战》一书,Tom著"); 135 136 System.out.println("==========首次修改文章完成==========="); 137 138 System.out.println("完整的信息" + editor); 139 140 articleMemento = editor.saveToMemento(); 141 142 draftsBox.addMemento(articleMemento); 143 144 System.out.println("==========保存到草稿箱==========="); 145 146 147 System.out.println("==========第2次修改文章==========="); 148 editor.setTitle("手写Spring"); 149 editor.setContent("本文节选自《Spring5核心原理与30个类手写实战》一书,Tom著"); 150 System.out.println("完整的信息" + editor); 151 System.out.println("==========第2次修改文章完成==========="); 152 153 System.out.println("==========第1次撤销==========="); 154 articleMemento = draftsBox.getMemento(); 155 editor.undoFromMemento(articleMemento); 156 System.out.println("完整的信息" + editor); 157 System.out.println("==========第1次撤销完成==========="); 158 159 160 System.out.println("==========第2次撤销==========="); 161 articleMemento = draftsBox.getMemento(); 162 editor.undoFromMemento(articleMemento); 163 System.out.println("完整的信息" + editor); 164 System.out.println("==========第2次撤销完成==========="); 165 166 } 167 }
3.备忘录模式优缺点
A.优点
a.简化发起人实体类职责,隔离状态存储与获取,实现了信息的封装,客户端无需关心状态的保存细节
b.提供状态回滚功能
B.缺点
a.消耗资源:如果需要保存的状态过多,每一次保存都会消耗很多内存