备忘录模式
源码下载地址:https://github.com/superRabbitMan/pattern-demo/tree/master/memento-demo
简介
备忘录(Memento):在不破坏封装性的前提下,捕获一个对象内部状态,并在该对象之外保存这个状态。这样以后就可以将该对象恢复到原先保存的状态。
通用类图及说明
实现方式
生活中最常用的计算器自己拥有备忘录的功能,用户计算完后软件会自动为用户记录最后几次的计算结果,我们可以模拟用户使用计算器的过程,以及打开备忘录查看记录。
package com.rabbit; /** * 备忘录发起人,模拟计算器加法运算 * Created by HASEE on 2018/4/29. */ public class Originator { private double num1; private double num2; //创建备忘录对象 public Memento createMemento() { return new Memento(num1, num2); } public Originator(double num1, double num2) { this.num1 = num1; this.num2 = num2; System.out.println(num1 + " + " + num2 + " = " + (num1 + num2)); } }
package com.rabbit; /** * 备忘录,要保存的属性 * Created by HASEE on 2018/4/29. */ public class Memento { private double num1;//计算器第一个数字 private double num2;//计算器第二个数字 private double result;//计算结果 public Memento(double num1, double num2) { this.num1 = num1; this.num2 = num2; this.result = num1 + num2; } public void show() { System.out.println(num1 + " + " + num2 + " = " + result); } }
package com.rabbit; import java.util.ArrayList; import java.util.List; /** * 备忘录管理者 * Created by HASEE on 2018/4/29. */ public class Caretaker { private List<Memento> mementos; public boolean addMenento(Memento memento) { if (mementos == null) { mementos = new ArrayList<>(); } return mementos.add(memento); } public List<Memento> getMementos() { return mementos; } public static Caretaker newInstance() { return new Caretaker(); } }
package com.rabbit; import org.junit.Test; import java.util.Random; /** * Created by HASEE on 2018/4/29. */ public class Demo { @Test public void test() { Caretaker c = Caretaker.newInstance(); //使用循环模拟用户使用计算器做加法运算 Random ran = new Random(1000); for (int i = 0; i < 5; i++) { //用户计算 Originator o = new Originator(ran.nextDouble(), ran.nextDouble()); //计算器软件将用户的计算做备份,以便可以查看历史 c.addMenento(o.createMemento()); } System.out.println("---------------------用户浏览历史记录---------------------"); for (Memento m : c.getMementos()) { m.show(); } System.out.println("---------------------用户选择一条记录查看----------------------"); c.getMementos().get(2).show(); } }
总结
备忘录模式比较适用于功能比较复杂,但是需要维护或记录属性历史的类,或者需要保存的属性只是众多属性的一小部分时,发起者(Originator)可以根据保存的备忘录(Memento)对象信息还原到之前的某一状态。
如果需要备份的是对象的全部属性,可以使用原型模式。