实例讲解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 备忘录模式的资料请关注我们其它相关文章!

(0)

相关推荐

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

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

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

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

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

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

  • 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设计模式之备忘录模式

    在讲述这个模式之前,我们先看一个案例:游戏回档 游戏的某个场景,一游戏角色有生命力.攻击力.防御力等数据,在打Boss前和后会不一样,我们允许玩家如果感觉与Boss决斗的效果不理想,可以让游戏恢复到决斗前.下面是代码: 游戏角色类,用来存储角色的生命力.攻击力.防御力的数据. public class GameRole { private int vit;//生命力 private int atk;//攻击力 private int def;//防御力 //状态显示 public void st

  • 深入理解Java设计模式之备忘录模式

    目录 一.什么是备忘录模式 二.备忘录模式的结构 三.备忘录模式的使用场景 四.备忘录模式的优缺点 五.备忘录模式的实现 总结 一.什么是备忘录模式 定义:在不破坏封闭的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态.这样以后就可将该对象恢复到原先保存的状态. 该模式用于保存对象当前状态,并且在之后可以再次恢复到此状态.备忘录模式实现的方式需要保证被保存的对象状态不能被对象从外部访问, 目的是为了保护被保存的这些对象状态的完整性以及内部实现不向外暴露 二.备忘录模式的结构 涉及角色:

  • 详解Java设计模式之备忘录模式的使用

    定义与结构     备忘录(Memento)模式又称标记(Token)模式.GOF给备忘录模式的定义为:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态.这样以后就可将该对象恢复到原先保存的状态. 在讲命令模式的时候,我们曾经提到利用中间的命令角色可以实现undo.redo的功能.从定义可以看出备忘录模式是专门来存放对象历史状态的,这对于很好的实现undo.redo功能有很大的帮助.所以在命令模式中undo.redo功能可以配合备忘录模式来实现. 其实单就实现保存一个对

  • 实例讲解Java设计模式编程中如何运用代理模式

    定义:  Provide a surrogate or placeholder for another object to control access to it. 为其他对象一种代理以控制对这个对象的访问. 一般描述: 一般包含的三个角色:抽象主题.具体主题.代理主题. 抽象主题:是一个抽象类或接口,是一个普通的业务类型定义. 具体主题:业务逻辑的具体执行者 代理角色:负责对真是角色的应用,把所有抽象主题类定义的方法限制委托给真实主题角色实现. 通用类图: 通用代码: package Pro

  • 实例讲解Java设计模式编程中的OCP开闭原则

    定义:一个软件实体如类.模块和函数应该对扩展开放,对修改关闭. 问题由来:在软件的生命周期内,因为变化.升级和维护等原因需要对软件原有代码进行修改时,可能会给旧代码中引入错误,也可能会使我们不得不对整个功能进行重构,并且需要原有代码经过重新测试. 解决方案:当软件需要变化时,尽量通过扩展软件实体的行为来实现变化,而不是通过修改已有的代码来实现变化.          开闭原则是面向对象设计中最基础的设计原则,它指导我们如何建立稳定灵活的系统.开闭原则可能是设计模式六项原则中定义最模糊的一个了,它

  • C++设计模式之备忘录模式(Memento)

    当我们在实际应用中需要提供撤销机制,当一个对象可能需要再后续操作中恢复其内部状态时,就需要使用备忘录模式.其本质就是对象的序列化和反序列化的过程,支持回滚操作. 作用 在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样以后就可以将该对象恢复到原先的状态. 类视图 实现 typedef struct sysstate; //假设的一个空结构,用来代表系统状态 //还原点 class Memento { public: Memento(sysstate &statein

  • Java设计模式之单件模式深入讲解

    目录 定义 Java单件模式 经典单件模式的实现 多线程单件模式的实现 急切创建实例 双重检查加锁 Python单件模式 模块实现 new关键字实现 装饰器实现 函数装饰器 类装饰器 定义 单件模式确保一个类只有一个实例,并提供一个全局访问点 Java单件模式 经典单件模式的实现 public class Singleton{ private static Singleton uniqueInstance; // 利用一个静态变量来记录Singleton类的唯一实例 private Single

随机推荐