备忘录模式(Memento):在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样以后就可以将该对象恢复到原来的状态。
案例:模拟保存游戏进度;
代码结构图:
1:创建游戏角色存储箱:
package MementoModel;
/**
* 角色状态存储箱,
* @author 我不是张英俊
*
*/
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 RoleStateMemento() {
// TODO Auto-generated constructor stub
}
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;
}
}
2:创建游戏角色:
package MementoModel; /** * 游戏玩家角色 * @author 我不是张英俊 * */ public class GamePlayer { private int vit; private int atk; private int def; //保存角色状态 public RoleStateMemento saveState(){ return (new RoleStateMemento(vit, atk, def)); } //恢复游戏状态 public void RecoveryState(RoleStateMemento memento){ this.setVit(memento.getVit()); this.setAtk(memento.getAtk()); this.setDef(memento.getDef()); } //状态显示 public void stateDisplayer(){ System.out.println("状态显示:"); System.out.println("生命值:"+this.vit); System.out.println("攻击力:"+this.atk); System.out.println("防御力:"+this.def); } //获得初始状态 public void getInitState(){ this.vit=100; this.atk=100; this.def=100; } //大战boss public void fight(){ this.vit=0; this.def=0; this.atk=0; } 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; } }
:创建角色状态管理器;
package MementoModel; /** * 角色状态管理者类 * 当存储不同角色的状态时可以使用,因为不同角色可能状态不一致,有的觉得有特定的状态。 * @author 我不是张英俊 * */ public class RoleStateCaretaker { private RoleStateMemento memento; public RoleStateMemento getMemento() { return memento; } public void setMemento(RoleStateMemento memento) { this.memento = memento; } }
4:创建测试类:
package MementoModel; /** * 模拟存储游戏进度机制 * 状态模式:(Memento)在不破坏封装性的前提下,补货一个对象的内部状态, * 并在该对象之外保存这个状态,这样以后就可以将该对象恢复到原先保存的状态。 * @author 我不是张英俊 * */ public class Test { public static void main(String[] args) { //大战boss前 GamePlayer one=new GamePlayer(); one.getInitState(); one.stateDisplayer(); //保存进度 RoleStateCaretaker caretaker=new RoleStateCaretaker(); caretaker.setMemento(one.saveState()); //大战boss one.fight(); one.stateDisplayer(); //恢复状态 one.RecoveryState(caretaker.getMemento()); one.stateDisplayer(); } }
控制台:
状态显示: 生命值:100 攻击力:100 防御力:100 状态显示: 生命值:0 攻击力:0 防御力:0 状态显示: 生命值:100 攻击力:100 防御力:100
总结:Memento模式比较适用于功能比较复杂的,但需要维护活记录实行历史信息的类,或者需要保存的树形只是
众多树形中的一小部分。例如:如果某个系统中使用命令模式时,需要实现命令的撤销功能,那么命令模式可以使用备忘录模式来存储可撤销操作的状态。
使用备忘录可以把复杂的对象内部信息对其他的对象屏蔽起来。
当角色的状态改变的时候,有可能这个状态时无效,这时候就可以使用暂时存储起来的备忘录将状态复原。
学习疑问:是否可以通过克隆来存储当前状态?