备忘录模式是在不破坏封装的原则下,捕获一个对象的状态,在对象之外保存这个状态,在必要时恢复到这个状态。
应用场景主要是将状态恢复到之前,例如Ctrl+Z的恢复,游戏从存档重新开始,JDBC事务控制。
备忘录模式的主要角色有三个:
Originator,发起人,职责是发起一次存档,将自身的状态存放到Memeto里面;
Memento,备忘录,存储Originator的状态;
Caretaker,负责人,负责保存好备忘录,不能对备忘录的内容进行操作和访问,只能够将备忘录传递给其他对象。
个人理解,Memento可以看作是Originator的一个副本,最简单的不用模式的方法,就是在Originator实现Clone接口,使用时Clone一个副本出来。
示例代码:
1 package com.khlin.memento; 2 3 /** 4 * 魂斗罗 5 * @author Kingsley 6 * 7 */ 8 public class Contra { 9 10 /* 11 * 剩下几条命 12 */ 13 private int life; 14 15 /* 16 * 手上的武器 17 */ 18 private String weapon; 19 20 public Contra(int life, String weapon) { 21 this.life = life; 22 this.weapon = weapon; 23 } 24 25 public int getLife() { 26 return this.life; 27 } 28 29 public String getWeapon() { 30 return this.weapon; 31 } 32 33 public Memento createMemento() { 34 return new Memento(life, weapon); 35 } 36 37 public void restoreMemento(Memento memento) { 38 this.life = memento.getLife(); 39 this.weapon = memento.getWeapon(); 40 } 41 42 public void die() { 43 this.life = 0; 44 this.weapon = null; 45 } 46 }
1 package com.khlin.memento; 2 3 public class Memento { 4 5 private int life; 6 7 private String weapon; 8 9 public Memento(int life, String weapon) { 10 this.life = life; 11 this.weapon = weapon; 12 } 13 14 public int getLife() { 15 return this.life; 16 } 17 18 public String getWeapon() { 19 return this.weapon; 20 } 21 }
1 package com.khlin.memento; 2 3 /** 4 * 备忘录的管理器 5 * @author Kingsley 6 * 7 */ 8 public class Caretaker { 9 10 private Memento memento; 11 12 public Memento getMemento() { 13 return memento; 14 } 15 16 public void setMemento(Memento memento) { 17 this.memento = memento; 18 } 19 }
客户端调用:
1 package com.khlin.memento; 2 3 public class App { 4 5 public static void main(String[] args) { 6 Contra contra = new Contra(10, "AK47"); 7 System.out.println("battle begins!!!"); 8 System.out.println("contra life " + contra.getLife() + " weapon " + contra.getWeapon()); 9 10 System.out.println("saving memento......"); 11 12 Caretaker caretaker = new Caretaker(); 13 Memento memento = contra.createMemento(); 14 caretaker.setMemento(memento);; 15 16 System.out.println("save memento successfully!!"); 17 18 contra.die(); 19 20 System.out.println("contra dies. life " + contra.getLife() + " weapon " + contra.getWeapon()); 21 22 System.out.println("restoring memento...."); 23 24 contra.restoreMemento(caretaker.getMemento()); 25 26 System.out.println("restore memento successfully!!"); 27 28 System.out.println("contra life " + contra.getLife() + " weapon " + contra.getWeapon()); 29 } 30 }
运行结果:
优点:
· 提供了状态的恢复机制
· 提供了状态保存状态的方法,用户不需要关心状态的保存实现
缺点:
· 消耗资源
应用场景:
备忘录模式又叫快照(snapshot)模式,因此可以用于需要保存某一时刻的状态的场景。
此外, 如果用一个接口来让其他对象得到这些状态,将会暴露对象的实现细节并破坏对象的封装性,一个对象不希望外界直接访问其内部状态,通过负责人可以间接访问其内部状态。