Java设计模式——备忘录模式

  • 需求
    游戏角色状态恢复问题
    游戏角色有攻击力和防御力,在大战Boss前保存自身的状态(攻击力和防御力),当大战Boss后攻击力和防御力下降,从备忘录对象恢复到大战前的状态。
  • 传统方案
    • 类图
      每一个游戏角色写一个状态类来保存角色的状态。
    • 传统方式的问题分析
      1)一个对象,就对应一个保存对象状态的对象。这样当我们游戏的对象很多时,不利于管理,开销也很大。
      2)传统方案只是简单地做备份,new出另外一个对象出来,再把需要备份的数据放到这个新对象中,但这就暴露了对象内部的细节。
  • 备忘录模式
    • 基本介绍
      1)备忘录模式(Memento Pattern)在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可以将该对象恢复到原先保存的状态。
      2)可以这样理解备忘录模式:现实生活中的备忘录是用来记录某些要去做的事情,或者是记录已经达成的共同意见的事情,以防忘记了。
      而在软件层面,备忘录模式有着相同的含义,备忘录对象主要用来记录一个对象的某种状态(在记录对象某种状态时可能是不同时期的,比如在某个时期里记录最新的对象状态。),或者某些数据,当要做回退时,可以从备忘录对象里获取原来的数据进行恢复操作。
      3)备忘录模式属于行为模式

    • 原理类图

    • 对原理类图的说明——备忘录模式的角色及职责
      1)Originator:对象(需要保存状态的对象)。
      2)Memento:备忘录对象,负责保存好记录,即Originator内部状态。
      3)Caretaker:守护者对象,负责保存多个备忘录对象,使用集合管理,提高效率。
      说明:若希望保存多个Originator对象的不同时间的状态或者不同属性值,可以使用HashMap实现。

    • 原理代码

      public class Originator {private String state;public String getState() {return state;}public void setState(String state) {this.state = state;}// 编写一个方法,可以保存当前对象的状态,并返回一个Mementopublic Memento saveStateMemento() {return new Memento(state);}// 通过备忘录对象,恢复状态public void getStateFromMemento(Memento memento) {state = memento.getState();}
      }
      public class Memento {private String state;public String getState() {return state;}public Memento(String state) {this.state = state;}}
      
      public class Caretaker {// 在List集合中会有很多的备忘录对象private List<Memento> mementoList = new ArrayList<Memento>();public void add(Memento memento) {mementoList.add(memento);}// 获取到第index个Originator的备忘录对象(即保存状态)public Memento get(int index) {return mementoList.get(index);}
      }
      
      public class Client {public static void main(String[] args) {Originator originator = new Originator();Caretaker caretaker = new Caretaker();originator.setState(" 状态#1 攻击力:100");// 保存了当前的状态caretaker.add(originator.saveStateMemento());originator.setState(" 状态#2 攻击力:80");caretaker.add(originator.saveStateMemento());originator.setState(" 状态#3 攻击力:50");caretaker.add(originator.saveStateMemento());// 希望恢复到状态#1System.out.println("当前状态是: " + originator.getState());originator.getStateFromMemento(caretaker.get(0));System.out.println("恢复后的状态是: " + originator.getState());}}
      
  • 备忘录模式——解决需求
    • 需求类图

    • 代码实现

      public class GameRole {// 攻击力private int vit;// 防御力private int def;public GameRole(int vit, int def) {super();this.vit = vit;this.def = def;}public int getVit() {return vit;}public void setVit(int vit) {this.vit = vit;}public int getDef() {return def;}public void setDef(int def) {this.def = def;}// 创建Memento,及根据游戏角色当前的状态得到一个Mementopublic Memento createMemento() {return new Memento(vit, def);}// 从备忘录对象,恢复GameRole的状态public void recoverGameRoleFromMemento(Memento memento) {this.vit = memento.getVit();this.def = memento.getDef();}// 显示当前游戏角色的状态public void display() {System.out.println("游戏角色当前的攻击力: " + this.vit);System.out.println("游戏角色当前的防御力: " + this.def);}}
      
      public class Memento {// 攻击力private int vit;// 防御力private int def;public Memento(int vit, int def) {super();this.vit = vit;this.def = def;}public int getVit() {return vit;}public void setVit(int vit) {this.vit = vit;}public int getDef() {return def;}public void setDef(int def) {this.def = def;}}
      
      // 守护者对象,保存游戏角色的状态
      public class Caretaker {// 如果只保存一次状态private Memento memento;// 如果对GameRole保存多次状态// private ArrayList<Memento> mementos;// 如果对多个游戏保存多个状态// private HashMap<String, List<Memento>> rolesMementos;public Memento getMemento() {return memento;}public void setMemento(Memento memento) {this.memento = memento;}}
      
      public class Client {public static void main(String[] args) {// 创建游戏角色GameRole gameRole = new GameRole(100, 100);System.out.println("和Boss大战前的状态");gameRole.display();// 把当前状态保存caretakerCaretaker caretaker = new Caretaker();caretaker.setMemento(gameRole.createMemento());System.out.println("和Boss开始大战~~~");// 攻击力和防御值都下降了gameRole.setVit(30);gameRole.setDef(30);System.out.println("和Boss大战后的状态");gameRole.display();System.out.println("大战后,使用备忘录对象恢复到大战前");gameRole.recoverGameRoleFromMemento(caretaker.getMemento());System.out.println("恢复后的状态");gameRole.display();}
      }
      
  • 备忘录模式的注意事项和细节
    1)给用户提供了一种可以恢复状态的机制,可以使用户能够比较方便地回到某个历史的状态。
    2)实现了信息的封装,使得用户不需要关心状态的保存细节。
    3)如果类的成员变量过多,势必会占用比较大的资源,而且每一次保存都会消耗一定的内存,这个需要注意。
    4)适用的应用场景:1、后悔药;2、打游戏时的存档;3、Windows里的ctrl+z;4、IE中的后退;5、数据库的事务管理(rollback)。
    5)为了节约内存,备忘录模式可以和原型模式配合使用。(原型模式可以快速复制一个对象,对资源进行节省。)

笔记课程参照:B站尚硅谷Java设计模式—— P127~P130

Java设计模式——备忘录模式相关推荐

  1. Java设计模式(备忘录模式-解释器模式-状态模式-策略模式-职责链模式)

    Java设计模式Ⅶ 1.备忘录模式 1.1 备忘录模式概述 1.2 代码理解 2.解释器模式 2.1 解释器模式概述 3.状态模式 3.1 状态模式概述 3.2 代码理解 4.策略模式 4.1 策略模 ...

  2. java设计模式---备忘录模式

    一.引子 俗话说:世上难买后悔药.所以凡事讲究个"三思而后行",但总常见有人做"痛心疾首"状:当初我要是--.如果真的有<大话西游>中能时光倒流的& ...

  3. Java设计模式--备忘录模式

    游戏角色状态恢复问题         游戏角色有攻击力和防御力,在大战Boss前保存自身的状态(攻击力和防御力),当大 战Boss后攻击力和防御力下降,从备忘录对象恢复到大战前的状态 传统方案解决游戏 ...

  4. JAVA 设计模式 备忘录模式

    用途 备忘录模式 (Memento) 在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态. 这样以后就可将该对象恢复到原先保存的状态. 备忘录模式是一种行为型模式. 结构 图- ...

  5. java设计模式-备忘录模式

    备忘录模式详解 备忘录模式又叫作快照模式或Token模式,是一种对象的行为模式.在备忘录模式里,一个备忘录是一个对象,它存储另一个对象(原发器对象)在某个瞬间的内部状态.备忘的目的就是为了以后在需要的 ...

  6. java memento_浅谈Java设计模式——备忘录模式(Memento)

    一.概述 在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态.这样以后就可将该对象恢复到原先保存的状态.它实现了对信息的封装,使得客户不需要关心状态保存的细节.保存就要消耗资源 ...

  7. Java设计模式—备忘录模式

    (尊重劳动成果,转载请注明出处:https://blog.csdn.net/qq_25827845/article/details/52462246冷血之心的博客) 目录 备忘录模式 定义如下: 通用 ...

  8. 设计模式-备忘录模式(Memento)-Java

    设计模式-备忘录模式(Memento)-Java 目录 文章目录 1.前言 2.示例案例-可悔棋的中国象棋 3.备忘录模式概述 3.1.备忘录模式定义 3.2.备忘录模式结构 3.3.备忘录模式结构图 ...

  9. Python设计模式-备忘录模式

    Python设计模式-备忘录模式 代码基于3.5.2,代码如下; #coding:utf-8 #备忘录模式 import randomclass gameCharacter():vitality = ...

最新文章

  1. python常见的排序算法_常见排序算法之python实现
  2. 机票预定系统类图_电商系统延时任务机制源码分享
  3. 简单的 密文认证方式
  4. Google Map 中混淆和压缩代码的简单示例
  5. druid-StatViewServlet配置
  6. Go-如何读取yaml,json,ini等配置文件
  7. python语法报错_Python语法的常见错误和处理异常
  8. python try catch语句_Java try catch语句
  9. linux 下socket通信,client断开service退出解决办法
  10. 简单5步,释放Mac磁盘空间
  11. 3、Go语言核心编程(高级篇)
  12. 融云联合ofo给大家送福利!
  13. 高分屏笔记本,如何处理程序提示“文本缩放比率要求为100%”
  14. springboot中Word转PDF技巧
  15. USB数据采集卡 USB1208LS、1608FS DAQami 软件功能有哪些
  16. matlab中主程序如何调用其它子程序,主程序怎样调用子程序
  17. 一些理论算法的学习资源推荐
  18. 计算机中央处理单元是哪些,1.1.1-1.1.2 计算机系统硬件基本组成 - 中央处理单元...
  19. [2019HDU多校第一场][HDU 6578][A. Blank]
  20. 删除U盘上的EFI分区

热门文章

  1. UE4-(场景)后期盒子(PostProcessVolume)之镜头眩光(Lens Flares)、景深(Depth of Field)、图像效果(Image Effects)
  2. 逍遥天龙八部服务器技能修改,泣诉逍遥三大难 技能修改势在必行
  3. 省级面板数据(2000-2019)四:固定资产投资+房地产(stata版)
  4. CFA一级学习笔记--权益(三)--订单执行以及有效性
  5. shell编程简单的实例
  6. 英文星期转换成中文星期!
  7. 张小龙2018PRO版微信公开课演讲全文 透露2018微信全新计划
  8. 【$fopen函数的用法】
  9. python re模块 正则表达式
  10. 树莓派更改python镜像源