设计模式之备忘录模式
程序员文章站
2024-01-01 15:21:46
很多人都玩游戏,也知道游戏进度保存的重要性。一般我们在与boss决战之前就会保存自己角色的数据,万一被boss打得屁股尿流挂掉了,我们也可以从之前保存的进度重新开始。 我们来程序模拟一下游戏进度的保存。 第一版,简单的实现: 代码无错未必优。这段代码的问题主要在于客户端的调用,这样写就是等于把整个游 ......
很多人都玩游戏,也知道游戏进度保存的重要性。一般我们在与boss决战之前就会保存自己角色的数据,万一被boss打得屁股尿流挂掉了,我们也可以从之前保存的进度重新开始。
我们来程序模拟一下游戏进度的保存。
第一版,简单的实现:
public class GameRole { //生命力 private int vit; //攻击力 private int atk; //防御力 private int 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; } //状态显示 public void stateDisplay(){ 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.atk = 0; this.def = 0; } }
public class Test { public static void main(String[] args) { // 大战前 GameRole lixiaoyao = new GameRole(); lixiaoyao.getInitState(); lixiaoyao.stateDisplay(); //保存进度 System.out.println("----------------"); GameRole backup = new GameRole(); backup.setVit(lixiaoyao.getVit()); backup.setAtk(lixiaoyao.getAtk()); backup.setDef(lixiaoyao.getDef()); //大战boss,损耗严重 System.out.println("----------------"); lixiaoyao.fight(); lixiaoyao.stateDisplay(); //恢复之前的状态 System.out.println("----------------"); lixiaoyao.setAtk(backup.getAtk()); lixiaoyao.setDef(backup.getDef()); lixiaoyao.setVit(backup.getVit()); lixiaoyao.stateDisplay(); } }
代码无错未必优。这段代码的问题主要在于客户端的调用,这样写就是等于把整个游戏角色的细节暴露给了客户端,客户端的职责就太大了。需要知道生命力,攻击力,防御力的细节,还要对他进行备份等等。显然,我们希望把存取游戏进度的细节封装起来,而且最好封装在外部的类中,以体现职责分离。这里需要用到一个新的设计模式-备忘录模式。
备忘录模式:在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样以后就可以将该对象恢复到原先保存的状态。
Memento模式比较适用于功能比较复杂的,但需要维护或记录属性历史的类,或需要保存的属性只是众多属性中的一部分时,Originator可以根据保存的Memento信息还原到之前的状态。比如在某个系统使用命令模式时,需要实现命令的撤销功能,那么命令模式可以使用备忘录模式来存储可撤销的操作状态。
第二版,游戏进度备忘
public class GameRole1 { //生命力 private int vit; //攻击力 private int atk; //防御力 private int 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; } //保存角色状态 public RoleStateMemoto saveState(){ return new RoleStateMemoto(vit,atk,def); } //恢复角色状态 public void recoveryState(RoleStateMemoto memoto){ this.vit = memoto.getVit(); this.atk = memoto.getDef(); this.def = memoto.getDef(); } //状态显示 public void stateDisplay(){ 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.atk = 0; this.def = 0; } }
public class RoleStateMemoto { //生命力 private int vit; //攻击力 private int atk; //防御力 private int def; public RoleStateMemoto(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; } }
public class RoleStateCareTaker { private RoleStateMemoto memoto; public RoleStateMemoto getMemoto() { return memoto; } public void setMemoto(RoleStateMemoto memoto) { this.memoto = memoto; } }
public class Test2 { public static void main(String[] args) { //大战boss前 GameRole1 lixiaoyao = new GameRole1(); lixiaoyao.getInitState(); lixiaoyao.stateDisplay(); //保存进度 RoleStateCareTaker stateAdmin = new RoleStateCareTaker(); stateAdmin.setMemoto(lixiaoyao.saveState()); //大战boss时,损耗严重 lixiaoyao.fight(); lixiaoyao.stateDisplay(); //恢复之前的状态 lixiaoyao.recoveryState(stateAdmin.getMemoto()); lixiaoyao.stateDisplay(); } }