备忘录模式(Memento Pattern)保存一个对象的某个状态,以便在适当的时候恢复对象。备忘录模式属于行为型模式。java
意图:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象以外保存这个状态。数据库
主要解决:所谓备忘录模式就是在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象以外保存这个状态,这样能够在之后将对象恢复到原先保存的状态。this
什么时候使用:不少时候咱们老是须要记录一个对象的内部状态,这样作的目的就是为了容许用户取消不肯定或者错误的操做,可以恢复到他原先的状态,使得他有"后悔药"可吃。spa
如何解决:经过一个备忘录类专门存储对象状态。code
关键代码:客户不与备忘录类耦合,与备忘录管理类耦合。对象
应用实例: 一、后悔药。 二、打游戏时的存档。 三、Windows 里的 ctri + z。 四、IE 中的后退。 四、数据库的事务管理。blog
优势: 一、给用户提供了一种能够恢复状态的机制,可使用户可以比较方便地回到某个历史的状态。 二、实现了信息的封装,使得用户不须要关心状态的保存细节。接口
缺点:消耗资源。若是类的成员变量过多,势必会占用比较大的资源,并且每一次保存都会消耗必定的内存。游戏
使用场景: 一、须要保存/恢复数据的相关状态场景。 二、提供一个可回滚的操做。事务
注意事项: 一、为了符合迪米特原则,还要增长一个管理备忘录的类。 二、为了节约内存,可以使用原型模式+备忘录模式。
Originator(发起人):负责建立一个备忘录Memento,用以记录当前时刻自身的内部状态,并可以使用备忘录恢复内部状态。Originator能够根据须要决定Memento存储本身的哪些内部状态。
Memento(备忘录):负责存储Originator对象的内部状态,并能够防止Originator之外的其余对象访问备忘录。备忘录有两个接口:Caretaker只能看到备忘录的窄接口,他只能将备忘录传递给其余对象。Originator却可看到备忘录的宽接口,容许它访问返回到先前状态所须要的全部数据。
Caretaker(管理者):负责备忘录Memento,不能对Memento的内容进行访问或者操做。
建立游戏角色
package com.cn.design_pattern.memento_pattern; /** * 游戏角色 * */ public class GameRole { // 体力 private int vit; // 攻击力 private int atk; public void init() { vit = 100; atk = 100; } public void show() { System.out.println("体力:" + vit); System.out.println("攻击力:" + atk); } public void fightBoss() { this.vit = 0; this.atk = 0; } public RoleStateMemento saveMemento() { return (new RoleStateMemento(vit, atk)); } public void recove(RoleStateMemento roleStateMemento) { this.vit = roleStateMemento.getVit(); this.atk = roleStateMemento.getAtk(); } }
建立游戏角色管理类
package com.cn.design_pattern.memento_pattern; /** * 游戏角色管理类 * */ public class RoleStateMange { private RoleStateMemento memento; public RoleStateMemento getMemento() { return memento; } public void setMemento(RoleStateMemento memento) { this.memento = memento; } }
建立存储类
package com.roc.meomory; /** * 存储类 * @author liaowp * */ public class RoleStateMemento { private int vit; private int atk; public RoleStateMemento(int vit, int atk){ this.vit=vit; this.atk=atk; } 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; } }
调用
/** * 备忘录模式 * @author liaowp * */ public class Client { public static void main(String[] args) { GameRole liaowp=new GameRole(); liaowp.init(); liaowp.show(); RoleStateMange adminMange=new RoleStateMange(); adminMange.setMemento(liaowp.saveMemento());//保存 liaowp.fightBoss(); liaowp.show(); liaowp.recove(adminMange.getMemento()); liaowp.show(); } }
适合功能比较复杂的,但须要维护或记录属性历史的功能。