实例讲解JAVA设计模式之备忘录模式

网友投稿 242 2022-12-03


实例讲解JAVA设计模式之备忘录模式

在讲述这个模式之前,我们先看一个案例:游戏回档

游戏的某个场景,一游戏角色有生命力、攻击力、防御力等数据,在打Boss前和后会不一样,我们允许玩家如果感觉与Boss决斗的效果不理想,可以让游戏恢复到决斗前。下面是代码:

游戏角色类,用来存储角色的生命力、攻击力、防御力的数据。

public class GameRole {

private int vit;//生命力

private int atk;//攻击力

private int 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;

}

//战斗

public void fight() {

//在与Boss大战后游戏数据损耗为0

this.vit = 0;

this.atk = 0;

this.def = 0;

}

//省略getter、setter方法

}

//测试方法

public class Test {

public static void main(String[] args) {

//大战Boss前

GameRole lixiaoyao = new GameRole();

lixiaoyao.getInitState();//Boss大战前,获得角色初始状态

lixiaoyao.stateDisplay();

//保存进度,通过游戏角色的新实例来保存进度

GameRole backup = new GameRole();

backup.http://setVit(lixiaoyao.getVit());

backup.setAtk(lixiaoyao.getAtk());

backup.setDef(lixiaoyao.getDef());

//大战Boss时,损耗严重,所有数据全部损耗为0

lixiaoyao.fight();

lixiaoyao.stateDisplay();

//恢复之前状态,重新来玩

lixiaoyao.setVit(backup.getVit());

lixihttp://aoyao.setAtk(backup.getAtk());

lixiaoyao.setDef(backup.getDef());

lixiaoyao.stateDisplay();

}

}

上面的代码实现了效果,但是不理想的是:main方法里暴露了太多“细节”,使得main方法需要知道“生命力、攻击力、防御力”这样的细节。以后需要增加“魔法值”或修改现有的“生命力”为“经验值”,这部分就要修改了。同样的道理也存在于恢复时的代码。显然,我们希望的是把这些“游戏角色”的存取状态细节封装起来,而且最好是封装在外部的类中。以体现职责分离。

下面介绍备忘录模式:http://runoob.com/design-pattern/memento-pattern.html

在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样以后就可将该对象恢复到原先保存的状态。

用备忘录模式优化案例

public class GameRole {

private int vit;//生命力

private int atk;//攻击力

private int 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;

}

//战斗

public void fight() {

//在与Boss大战后游戏数据损耗为0

this.vit = 0;

this.atk = 0;

this.def = 0;

}

//新增“保存角色状态”方法,将游戏角色的三个状态值通过实例化“角色状态存储箱”返回

public RoleStateMemento saveState() {

return new RoleStateMemento(vit, atk, def);

}

//新增“恢复角色状态”方法,可将外部的“角色状态存储箱”中的状态值恢复给游戏角色

public void recoveryState(RoleStateMemento memento) {

this.vit = memento.getAtk();

this.atk = memento.getAtk();

this.def = memento.getDef();

}

//省略getter、setter方法

}

//角色状态存储箱类

public class RoleStateMemento {

private int vit;//生命力

private int atk;//攻击力

private int def;//防御力

//将生命力、攻击力、防御力存入状态存储箱对象中

public RoleStateMemento(int vit, int atk, int def) {

super();

this.vit = vit;

this.atk = atk;

this.def = def;

}

//省略getter、setter方法

}

//角色状态管理者类

public class RoleStateCaretaker {

private RoleStateMemento memento;

public RoleStateMemento getMemento() {

return memento;

}

public void setMemento(RoleStateMemento memento) {

this.memento = memento;

}

}

//测试方法

public class Test {

public static void main(String[] args) {

//大战Boss前

GameRole lixiaoyao = new GameRole();

lixiaoyao.getInitState();//Boss大战前,获得角色初始状态

lixiaoyao.stateDisplay();

//保存进度,由于封装在Memento中,因此我们并不知道保存了哪些具体的数据

RoleStateCaretaker stateAdmin = new RoleStateCaretaker();

stateAdmin.setMemento(lixiaoyao.saveState());

//大战Boss时,损耗严重

lixiaoyao.fight();

lixiaoyao.stateDisplay();

//恢复之前的状态

lixiaoyao.recoveryState(stateAdmin.getMemento());

lixiaoyao.stateDisplay();

}

}

输出结果同上。

肯定有人会问:对于“角色状态”的保存,直接调用RoleStateMemento进行set和get不就行了,为什么还需要一个RoleStateCaretaker类呢?

这是为了符合迪米特法则进行的优化!

备忘录模式也是有缺点的,角色状态需要完整存储到备忘录对象中,如果状态数据很大很多,那么在资源消耗上,备忘录对象会非常耗内存。所以也不是用的越多越好。

以上就是实例讲解java设计模式之备忘录模式的详细内容,更多关于JAVA 备忘录模式的资料请关注我们其它相关文章!


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:深入理解JAVA 备忘录模式
下一篇:docker启动Java程序的方法步骤
相关文章

 发表评论

暂时没有评论,来抢沙发吧~