实例讲解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方法需要知道“生命力、攻击力、防御力”这样的细节。以后需要增加“魔法值”或修改现有的“生命力”为“经验值”,这部分就要修改了。同样的道理也存在于恢复时的代码。显然,我们希望的是把这些“游戏角色”的存取状态细节封装起来,而且最好是封装在外部的类中。以体现职责分离。

下面介绍备忘录模式: http://www.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 备忘录模式的资料请关注我们其它相关文章

时间:2020-06-24

Java设计模式之备忘录模式(Memento模式)介绍

Memento定义:memento是一个保存另外一个对象内部状态拷贝的对象,这样以后就可以将该对象恢复到原先保存的状态. Memento模式相对也比较好理解,我们看下列代码: 复制代码 代码如下: public class Originator { private int number; private File file = null; public Originator(){} // 创建一个Memento public Memento getMemento(){ return new Me

JAVA设计模式之备忘录模式原理与用法详解

本文实例讲述了JAVA设计模式之备忘录模式.分享给大家供大家参考,具体如下: 备忘录模式:又叫做快照模式,指在不破坏封装性的前提下,获取到一个对象的内部状态,并在对象之外记录或保存这个状态.在有需要的时候可将该对象恢复到原先保存的状态.我们相当于把对象原始状备份保留,所以叫备忘录模式. *模式 角色对象组成: 1.发起者对象:负责创建一个备忘录来记录当前对象的内部状态,并可使用备忘录恢复内部状态. 2.备忘录对象:负责存储发起者对象的内部状态,并防止其他对象访问备忘录. 3.管理者对象:负责备忘

23种设计模式(18)java备忘录模式

23种设计模式第十八篇:java备忘录模式 定义:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态.这样就可以将该对象恢复到原先保存的状态. 类型:行为类 类图: 我们在编程的时候,经常需要保存对象的中间状态,当需要的时候,可以恢复到这个状态.比如,我们使用Eclipse进行编程时,假如编写失误(例如不小心误删除了几行代码),我们希望返回删除前的状态,便可以使用Ctrl+Z来进行返回.这时我们便可以使用备忘录模式来实现. 备忘录模式的结构 发起人:记录当前时刻的内部状态

Java设计模式之备忘录模式_动力节点Java学院

定义:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态.这样就可以将该对象恢复到原先保存的状态 类型:行为类 类图: 我们在编程的时候,经常需要保存对象的中间状态,当需要的时候,可以恢复到这个状态.比如,我们使用Eclipse进行编程时,假如编写失误(例如不小心误删除了几行代码),我们希望返回删除前的状态,便可以使用Ctrl+Z来进行返回.这时我们便可以使用备忘录模式来实现. 备忘录模式的结构 发起人:记录当前时刻的内部状态,负责定义哪些属于备份范围的状态,负责创建和

Java设计模式之迭代器模式_动力节点Java学院整理

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

定义:提供一种方法访问一个容器对象中各个元素,而又不暴露该对象的内部细节. 类型:行为类模式 类图: 如果要问Java中使用最多的一种模式,答案不是单例模式,也不是工厂模式,更不是策略模式,而是迭代器模式,先来看一段代码吧: public static void print(Collection coll){ Iterator it = coll.iterator(); while(it.hasNext()){ String str = (String)it.next(); System.out

Java设计模式之解释器模式_动力节点Java学院整理

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

定义:给定一种语言,定义他的文法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中句子. 类型:行为类模式 类图: 解释器模式是一个比较少用的模式,本人之前也没有用过这个模式.下面我们就来一起看一下解释器模式. 解释器模式的结构 抽象解释器:声明一个所有具体表达式都要实现的抽象接口(或者抽象类),接口中主要是一个interpret()方法,称为解释操作.具体解释任务由它的各个实现类来完成,具体的解释器分别由终结符解释器TerminalExpression和非终结符解释器Nonterm

Java设计模式之策略模式_动力节点Java学院整理

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

定义:定义一组算法,将每个算法都封装起来,并且使他们之间可以互换. 类型:行为类模式 类图: 策略模式是对算法的封装,把一系列的算法分别封装到对应的类中,并且这些类实现相同的接口,相互之间可以替换.在前面说过的行为类模式中,有一种模式也是关注对算法的封装–模版方法模式,对照类图可以看到,策略模式与模版方法模式的区别仅仅是多了一个单独的封装类Context,它与模版方法模式的区别在于:在模版方法模式中,调用算法的主体在抽象的父类中,而在策略模式中,调用算法的主体则是封装到了封装类Context中

Java设计模式之代理模式_动力节点Java学院整理

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

引言 Java 动态代理机制的出现,使得 Java 开发人员不用手工编写代理类,只要简单地指定一组接口及委托类对象,便能动态地获得代理类.代理类会负责将所有的方法调用分派到委托对象上反射执行,在分派执行的过程中,开发人员还可以按需调整委托类对象及其功能,这是一套非常灵活有弹性的代理框架.通过阅读本文,读者将会对 Java 动态代理机制有更加深入的理解.本文首先从 Java 动态代理的运行机制和特点出发,对其代码进行了分析,推演了动态生成类的内部实现. 代理:设计模式 代理是一种常用的设计模式,其

Java设计模式之命令模式_动力节点Java学院整理

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

定义:将一个请求封装成一个对象,从而让你使用不同的请求把客户端参数化,对请求排队或者记录请求日志,可以提供命令的撤销和恢复功能. 类型:行为类模式 类图: 命令模式的结构 顾名思义,命令模式就是对命令的封装,首先来看一下命令模式类图中的基本结构: Command类:是一个抽象类,类中对需要执行的命令进行声明,一般来说要对外公布一个execute方法用来执行命令. ConcreteCommand类:Command类的实现类,对抽象类中声明的方法进行实现. Client类:最终的客户端调用类.

设计模式之原型模式_动力节点Java学院整理

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

定义:用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象. 类型:创建类模式 类图: 原型模式主要用于对象的复制,它的核心是就是类图中的原型类Prototype.Prototype类需要具备以下两个条件: 实现Cloneable接口.在java语言有一个Cloneable接口,它的作用只有一个,就是在运行时通知虚拟机可以安全地在实现了此接口的类上使用clone方法.在java虚拟机中,只有实现了这个接口的类才可以被拷贝,否则在运行时会抛出CloneNotSupportedExcepti

Java异常继承结构解析_动力节点Java学院整理

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

Java异常类层次结构图: 异常的英文单词是exception,字面翻译就是"意外.例外"的意思,也就是非正常情况.事实上,异常本质上是程序上的错误,包括程序逻辑错误和系统错误.比如使用空的引用.数组下标越界.内存溢出错误等,这些都是意外的情况,背离我们程序本身的意图.错误在我们编写程序的过程中会经常发生,包括编译期间和运行期间的错误,在编译期间出现的错误有编译器帮助我们一起修正,然而运行期间的错误便不是编译器力所能及了,并且运行期间的错误往往是难以预料的.假若程序在运行期间出现了错误

深入理解Java中的final关键字_动力节点Java学院整理

Java中的final关键字非常重要,它可以应用于类.方法以及变量.这篇文章中我将带你看看什么是final关键字?将变量,方法和类声明为final代表了什么?使用final的好处是什么?最后也有一些使用final关键字的实例.final经常和static一起使用来声明常量,你也会看到final是如何改善应用性能的. final关键字的含义? final在Java中是一个保留的关键字,可以声明成员变量.方法.类以及本地变量.一旦你将引用声明作final,你将不能改变这个引用了,编译器会检查代码,如

Java Date类常用示例_动力节点Java学院整理

Date类 在JDK1.0中,Date类是唯一的一个代表时间的类,但是由于Date类不便于实现国际化,所以从JDK1.1版本开始,推荐使用Calendar类进行时间和日期处理.这里简单介绍一下Date类的使用. 1.使用Date类代表当前系统时间 Date d = new Date(); System.out.println(d); 使用Date类的默认构造方法创建出的对象就代表当前时间,由于Date类覆盖了toString方法,所以可以直接输出Date类型的对象,显示的结果如下: Sun Ma

原文 

https://www.zhangshengrong.com/p/7B1LqyEwaw/

本站部分文章源于互联网,本着传播知识、有益学习和研究的目的进行的转载,为网友免费提供。如有著作权人或出版方提出异议,本站将立即删除。如果您对文章转载有任何疑问请告之我们,以便我们及时纠正。

PS:推荐一个微信公众号: askHarries 或者qq群:474807195,里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多

转载请注明原文出处:Harries Blog™ » 实例讲解JAVA设计模式之备忘录模式

赞 (0)
分享到:更多 ()

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址