备忘录这个词汇你们应该都不陌生,我就常用备忘录来记录一些比较重要的或者容易遗忘的信息,与之相关的最多见的应用有许多,好比游戏存档,咱们玩游戏的时候确定有存档功能,旨在下一次登陆游戏时能够从上次退出的地方继续游戏,或者对复活点进行存档,若是挂掉了则能够读取复活点的存档信息从新开始。与之相相似的就是数据库的事务回滚,或者重作日志redo log等。git
备忘录模式(Memento),在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象以外保存着这个状态。这样之后就可将该对象恢复到原先保存的状态。UML结构图以下:数据库
其中,Originator是发起人,负责建立一个备忘录Memento,用以记录当前时刻它的内部状态,并可以使用备忘录恢复内部状态;Memento是备忘录,负责存储Originator对象的内部状态,并可防止Originator之外的其余对象访问备忘录Memento;Caretaker是管理者,负责保存好备忘录的Memento,不能对备忘录的内容进行操做或检查。浏览器
记录当前时刻的内部状态,并负责建立和恢复备忘录数据,容许访问返回到先前状态所需的全部数据。测试
1 public class Originator { 2 3 private String state; 4 5 public String getState() { 6 return state; 7 } 8 9 public void setState(String state) { 10 this.state = state; 11 } 12 13 public Memento createMento() { 14 return (new Memento(state)); 15 } 16 17 public void setMemento(Memento memento) { 18 state = memento.getState(); 19 } 20 21 public void show() { 22 System.out.println("state = " + state); 23 } 24 25 }
负责存储Originator发起人对象的内部状态,在须要的时候提供发起人须要的内部状态。this
1 public class Memento { 2 3 private String state; 4 5 public Memento(String state) { 6 this.state = state; 7 } 8 9 public String getState() { 10 return state; 11 } 12 13 }
对备忘录进行管理、保存和提供备忘录,只能将备忘录传递给其余角色。spa
1 public class Caretaker { 2 3 private Memento memento; 4 5 public Memento getMemento() { 6 return memento; 7 } 8 9 public void setMemento(Memento memento) { 10 this.memento = memento; 11 } 12 13 }
下面编写一小段代码测试一下,即先将状态置为On,保存后再将状态置为Off,而后经过备忘录管理员角色恢复初始状态。日志
1 public class Client { 2 3 public static void main(String[] args) { 4 Originator originator = new Originator(); 5 originator.setState("On"); //Originator初始状态 6 originator.show(); 7 8 Caretaker caretaker = new Caretaker(); 9 caretaker.setMemento(originator.createMento()); 10 11 originator.setState("Off"); //Originator状态变为Off 12 originator.show(); 13 14 originator.setMemento(caretaker.getMemento()); //回复初始状态 15 originator.show(); 16 } 17 18 }
运行结果以下:code
下面以游戏存档为例,看一下如何用备忘录模式实现。UML图以下:对象
简单记录了游戏角色的生命力、攻击力、防护力,经过saveState()方法来保存当前状态,经过recoveryState()方法来恢复角色状态。blog
1 public class GameRole { 2 3 private int vit; //生命力 4 private int atk; //攻击力 5 private int def; //防护力 6 7 public int getVit() { 8 return vit; 9 } 10 public void setVit(int vit) { 11 this.vit = vit; 12 } 13 public int getAtk() { 14 return atk; 15 } 16 public void setAtk(int atk) { 17 this.atk = atk; 18 } 19 public int getDef() { 20 return def; 21 } 22 public void setDef(int def) { 23 this.def = def; 24 } 25 26 //状态显示 27 public void stateDisplay() { 28 System.out.println("角色当前状态:"); 29 System.out.println("体力:" + this.vit); 30 System.out.println("攻击力:" + this.atk); 31 System.out.println("防护力: " + this.def); 32 System.out.println("-----------------"); 33 } 34 35 //得到初始状态 36 public void getInitState() { 37 this.vit = 100; 38 this.atk = 100; 39 this.def = 100; 40 } 41 42 //战斗后 43 public void fight() { 44 this.vit = 0; 45 this.atk = 0; 46 this.def = 0; 47 } 48 49 //保存角色状态 50 public RoleStateMemento saveState() { 51 return (new RoleStateMemento(vit, atk, def)); 52 } 53 54 //恢复角色状态 55 public void recoveryState(RoleStateMemento memento) { 56 this.vit = memento.getVit(); 57 this.atk = memento.getAtk(); 58 this.def = memento.getDef(); 59 } 60 61 }
备忘录类,用于存储角色状态。
1 public class RoleStateMemento { 2 3 private int vit; //生命力 4 private int atk; //攻击力 5 private int def; //防护力 6 7 public RoleStateMemento(int vit, int atk, int def) { 8 this.vit = vit; 9 this.atk = atk; 10 this.def = def; 11 } 12 13 public int getVit() { 14 return vit; 15 } 16 17 public void setVit(int vit) { 18 this.vit = vit; 19 } 20 21 public int getAtk() { 22 return atk; 23 } 24 25 public void setAtk(int atk) { 26 this.atk = atk; 27 } 28 29 public int getDef() { 30 return def; 31 } 32 33 public void setDef(int def) { 34 this.def = def; 35 } 36 37 }
备忘录管理者。
1 public class RoleStateCaretaker { 2 3 private RoleStateMemento memento; 4 5 public RoleStateMemento getMemento() { 6 return memento; 7 } 8 9 public void setMemento(RoleStateMemento memento) { 10 this.memento = memento; 11 } 12 13 }
下面编写一个简单的程序测试一下,编写逻辑大体为打boss前存档,打boss失败了,读档。
1 public class Client { 2 3 public static void main(String[] args) { 4 //打boss前 5 GameRole gameRole = new GameRole(); 6 gameRole.getInitState(); 7 gameRole.stateDisplay(); 8 9 //保存进度 10 RoleStateCaretaker caretaker = new RoleStateCaretaker(); 11 caretaker.setMemento(gameRole.saveState()); 12 13 //打boss失败 14 gameRole.fight(); 15 gameRole.stateDisplay(); 16 17 //恢复状态 18 gameRole.recoveryState(caretaker.getMemento()); 19 gameRole.stateDisplay(); 20 } 21 22 }
运行结果以下: