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

 更新时间:2020年06月24日 15:18:06   作者:认真对待  
这篇文章主要介绍了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.setVit(lixiaoyao.getVit());
  backup.setAtk(lixiaoyao.getAtk());
  backup.setDef(lixiaoyao.getDef());
  
  //大战Boss时,损耗严重,所有数据全部损耗为0
  lixiaoyao.fight();
  lixiaoyao.stateDisplay();
  
  //恢复之前状态,重新来玩
  lixiaoyao.setVit(backup.getVit());
  lixiaoyao.setAtk(backup.getAtk());
  lixiaoyao.setDef(backup.getDef());
  lixiaoyao.stateDisplay();
  
 }
}

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

下面介绍备忘录模式:https://www.jb51.net/article/189469.htm

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

用备忘录模式优化案例

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 备忘录模式的资料请关注脚本之家其它相关文章!

相关文章

  • Java 8中default方法能做什么?不能做什么?

    Java 8中default方法能做什么?不能做什么?

    这篇文章主要给大家介绍了关于Java 8中default方法能做什么?不能做什么?文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。
    2018-04-04
  • 浅谈Java对象禁止使用基本类型

    浅谈Java对象禁止使用基本类型

    本文主要介绍了浅谈Java对象禁止使用基本类型,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-02-02
  • 基于spring实现websocket实时推送实例

    基于spring实现websocket实时推送实例

    这篇文章主要为大家详细介绍了基于spring实现websocket实时推送实例,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-03-03
  • 深入讲解Java synchronized的核心原理

    深入讲解Java synchronized的核心原理

    这篇文章主要为大家详细介绍了Java中synchronized的核心原理以及简单的用法,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2023-07-07
  • Java 实现实时监听文件夹是否有新文件增加并上传服务器功能

    Java 实现实时监听文件夹是否有新文件增加并上传服务器功能

    本文中主要陈述一种实时监听文件夹中是否有文件增加的功能,可用于实际文件上传功能的开发。本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友参考下吧
    2019-09-09
  • Java多个线程同时执行的方法

    Java多个线程同时执行的方法

    这篇文章主要介绍了Java多线程处理文件详解与代码示例,通过本文的介绍和代码示例,我们了解了如何使用Java多线程来处理文件,使用多线程技术可以显著提高文件处理的效率,特别是对于大量文件的处理任务,需要的朋友可以参考下
    2024-12-12
  • springboot项目之相互依赖报错问题(基于idea)

    springboot项目之相互依赖报错问题(基于idea)

    这篇文章主要介绍了springboot项目之相互依赖报错问题(基于idea),具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-02-02
  • 给新来的同事讲where 1=1是什么意思

    给新来的同事讲where 1=1是什么意思

    当遇到多个查询条件,使用where 1=1 可以很方便的解决我们的问题,但这究竟有什么意思呢?所以下面这篇文章主要给大家介绍了关于where 1=1是什么意思,需要的朋友可以参考下
    2021-12-12
  • SpringBoot如何使用Template请求http接口

    SpringBoot如何使用Template请求http接口

    在Spring Boot中,如果你想要通过模板(template)的方式连接HTTP服务,并发送HTTP请求,有几种不同的方式可以实现,但最直接和常用的方式之一是使用RestTemplate,这篇文章主要介绍了SpringBoot使用Template请求http接口,需要的朋友可以参考下
    2024-08-08
  • spring-boot-autoconfigure模块用法详解

    spring-boot-autoconfigure模块用法详解

    autoconfigure就是自动配置的意思,spring-boot通过spring-boot-autoconfigure体现了"约定优于配置"这一设计原则,而spring-boot-autoconfigure主要用到了spring.factories和几个常用的注解条件来实现自动配置,思路很清晰也很简单,感兴趣的朋友跟随小编一起看看吧
    2022-11-11

最新评论