Loading... # 设计模式(十五)——备忘录模式 ## 参考 > 大话设计模式  ——  程杰 著 ## 目录 [设计模式(一)——简单工厂模式](https://www.princelei.club/archives/67.html) [设计模式(二)——策略模式](https://www.princelei.club/archives/68.html) [设计模式(三)——设计原则](https://www.princelei.club/archives/116.html) [设计模式(四)——装饰模式](https://www.princelei.club/archives/117.html) [设计模式(五)——代理模式](https://www.princelei.club/archives/119.html) [设计模式(六)——工厂方法模式](https://www.princelei.club/archives/132.html) [设计模式(七)——原型模式](https://www.princelei.club/archives/133.html) [设计模式(八)——模板方法模式](https://www.princelei.club/archives/134.html) [设计模式(九)——外观模式](https://www.princelei.club/archives/135.html) [设计模式(十)——建造者模式](https://www.princelei.club/archives/136.html) [设计模式(十一)——观察者模式](https://www.princelei.club/archives/137.html) [设计模式(十二)——抽象工厂模式](https://www.princelei.club/archives/138.html) [设计模式(十三)——状态模式](https://www.princelei.club/archives/139.html) [设计模式(十四)——适配器模式](https://www.princelei.club/archives/140.html) [设计模式(十五)——备忘录模式](https://www.princelei.club/archives/141.html) [设计模式(十六)——组合模式](https://www.princelei.club/archives/147.html) [设计模式(十七)——迭代器模式](https://www.princelei.club/archives/148.html) [设计模式(十八)——单例模式](https://www.princelei.club/archives/157.html) [设计模式(十九)——桥接模式](https://www.princelei.club/archives/159.html) [设计模式(二十)——命令模式](https://www.princelei.club/archives/160.html) [设计模式(二十一)——职责链模式](https://www.princelei.club/archives/161.html) [设计模式(二十二)——中介者模式](https://www.princelei.club/archives/162.html) [设计模式(二十三)——享元模式](https://www.princelei.club/archives/163.html) [设计模式(二十四)——解释器模式](https://www.princelei.club/archives/173.html) [设计模式(二十五)——访问者模式](https://www.princelei.club/archives/174.html) ## 何为备忘录模式 - 备忘录模式(Memento):在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可以将该对象恢复到原先保存的状态。 ## 示例 游戏进度备忘录 ``` /** * 游戏角色类(Originator) */ public class GameRole { //生命力 private int vit; //攻击力 private int atk; //防御力 private int def; public int getVit() { return vit; } public int getAtk() { return atk; } public int getDef() { return def; } //状态显示 public void stateDisplay() { System.out.println("角色当前状态:"); System.out.println("体力: " + vit); System.out.println("攻击力: " + atk); System.out.println("防御力: " + def); System.out.println(""); } //获得初始状态 public void getInitState() { vit = 100; atk = 100; def = 100; } //战斗 public void fight() { vit = 0; atk = 0; def = 0; } //保存角色状态 public RoleStateMemento saveState() { return new RoleStateMemento(vit, atk, def); } //恢复角色状态 public void recoveryState(RoleStateMemento memento) { vit = memento.getVit(); atk = memento.getAtk(); def = memento.getDef(); } } ``` ``` /** * 角色状态储存箱(Memento) */ public class RoleStateMemento { private int vit; private int atk; private int def; public RoleStateMemento(int vit, int atk, int def) { this.vit = vit; this.atk = atk; this.def = def; } public int getVit() { return vit; } public void setVit(int vit) { this.vit = vit; } public int getAtk() { return atk; } public void setAtk(int atk) { this.atk = atk; } public int getDef() { return def; } public void setDef(int def) { this.def = def; } } ``` ``` /** * 角色状态管理者(Caretaker) */ public class RoleStateCaretaker { private RoleStateMemento memento; public RoleStateCaretaker(RoleStateMemento memento){ this.memento = memento; } public RoleStateMemento getMemento() { return memento; } public void setMemento(RoleStateMemento memento) { this.memento = memento; } } ``` ``` /** * 客户端 */ public class MainClass { public static void main(String[] args) { //大战Boss前 GameRole role = new GameRole(); role.getInitState();//初始状态。三项指标都是100 role.stateDisplay(); //保存进度,由于封装在Menento中,因此我们并不知道保存了哪些具体数据 RoleStateCaretaker stateAdmin = new RoleStateCaretaker(role.saveState()); //大战Boss时,损耗严重 role.fight();//开始打Boss,三项指标归零,GameOver role.stateDisplay(); //恢复之前状态 role.recoveryState(stateAdmin.getMemento()); role.stateDisplay(); } } ``` 输出: ``` 角色当前状态: 体力: 100 攻击力: 100 防御力: 100 角色当前状态: 体力: 0 攻击力: 0 防御力: 0 角色当前状态: 体力: 100 攻击力: 100 防御力: 100 ``` 把要保存的细节封装在了Memento中,哪一天要更改保存的细节也不用影响客户端。 ## 何时使用备忘录模式 备忘录模式比较适用于功能比较复杂的,但需要维护或记录历史属性的类,或者需要保存的属性只是众多属性中的一小部分时,Originator可以根据保存的Memento信息还原到前一状态。如果在某个系统中使用命令模式时,需要实现命令的撤销功能,那么命令模式可以使用备忘录模式来储存可撤销操作的状态。使用备忘录模式可以把复杂对象内部信息对其他的对象屏蔽起来,当角色状态改变的时候,有可能这个状态无效,这时候就可以使用暂时储存起来的备忘录将状态复原。备忘录模式也是有缺点的,角色状态需要完整储存到备忘录对象中,如果状态数据很大很多,那么在资源消耗上,备忘录对象会非常耗内存。 Last modification:June 11th, 2020 at 06:23 pm © 允许规范转载