经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » Java相关 » 设计模式 » 查看文章
大话设计模式笔记(十五)の备忘录模式
来源:cnblogs  作者:callmeDevil  时间:2019/8/12 9:14:30  对本文有异议

举个栗子

问题描述

打游戏存进度。

简单实现

GameRole

  1. /**
  2. * 游戏角色
  3. * Created by callmeDevil on 2019/8/11.
  4. */
  5. public class GameRole {
  6. // 生命力
  7. private int vit;
  8. // 攻击力
  9. private int atk;
  10. // 防御力
  11. private int def;
  12. // 状态显示
  13. public void stateDisplay() {
  14. System.out.println("角色当前状态:");
  15. System.out.println(String.format("体力:%s", this.vit));
  16. System.out.println(String.format("攻击力:%s", this.atk));
  17. System.out.println(String.format("防御力:%s", this.def));
  18. System.out.println();
  19. }
  20. // 获得初始状态
  21. public void getInitState() {
  22. // 数据通常来自本机磁盘或远程数据库
  23. this.vit = 100;
  24. this.atk = 100;
  25. this.def = 100;
  26. }
  27. // 战斗
  28. public void fight(){
  29. // 在与Boss大战后游戏数据损耗为0
  30. this.vit = 0;
  31. this.atk = 0;
  32. this.def = 0;
  33. }
  34. // 省略 get set
  35. }

测试

  1. public class Test {
  2. public static void main(String[] args) {
  3. // 大战Boss前
  4. GameRole lufi = new GameRole();
  5. // 获得初始角色状态
  6. lufi.getInitState();
  7. lufi.stateDisplay();
  8. // 通过“游戏角色”新实例,保存进度
  9. GameRole backup = new GameRole();
  10. backup.setVit(lufi.getVit());
  11. backup.setAtk(lufi.getAtk());
  12. backup.setDef(lufi.getDef());
  13. // 大战Boss时,损耗严重,全部为0
  14. lufi.fight();
  15. lufi.stateDisplay();
  16. // GameOver不甘心,恢复进度,重新玩过
  17. lufi.setVit(backup.getVit());
  18. lufi.setAtk(backup.getAtk());
  19. lufi.setDef(backup.getDef());
  20. lufi.stateDisplay();
  21. }
  22. }

测试结果

  1. 角色当前状态:
  2. 体力:100
  3. 攻击力:100
  4. 防御力:100
  5. 角色当前状态:
  6. 体力:0
  7. 攻击力:0
  8. 防御力:0
  9. 角色当前状态:
  10. 体力:100
  11. 攻击力:100
  12. 防御力:100

存在问题

在客户端调用这段,把整个游戏角色的细节暴露了,职责太大,需要知道游戏角色的生命力、攻击力、防御力这些细节,还要进行备份。如果以后需要增加“魔法力”或修改现有的某种力,那这部分代码就需要修改,同样恢复时也是一样的问题。

备忘录模式

定义

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

UML图

代码实现

GameRole

  1. /**
  2. * 游戏角色
  3. * Created by callmeDevil on 2019/8/11.
  4. */
  5. public class GameRole {
  6. // 属性与简单实现GameRole相同
  7. // 保存角色状态
  8. public RoleStateMemento saveState() {
  9. return new RoleStateMemento(vit, atk, def);
  10. }
  11. // 恢复角色状态
  12. public void recoveryState(RoleStateMemento memento) {
  13. this.vit = memento.getVit();
  14. this.atk = memento.getAtk();
  15. this.def = memento.getDef();
  16. }
  17. // 其余方法与简单实现相同
  18. }

RoleStateMemento

  1. /**
  2. * 角色状态存储类
  3. * Created by callmeDevil on 2019/8/11.
  4. */
  5. public class RoleStateMemento {
  6. // 属性与 简单实现 GameRole 相同
  7. // 将生命力、攻击力、防御力存入状态存储箱对象中
  8. public RoleStateMemento(int vit, int atk, int def){
  9. this.vit = vit;
  10. this.atk = atk;
  11. this.def = def;
  12. }
  13. // 省略 get set
  14. }

RoleStateCaretaker

  1. /**
  2. * 游戏状态管理者
  3. * Created by callmeDevil on 2019/8/11.
  4. */
  5. public class RoleStateCaretaker {
  6. private RoleStateMemento memento;
  7. // 省略 get set
  8. }

测试

  1. public class Test {
  2. public static void main(String[] args) {
  3. // 大战Boss前
  4. GameRole lufi = new GameRole();
  5. lufi.getInitState();
  6. lufi.stateDisplay();
  7. // 保存游戏进度
  8. RoleStateCaretaker stateAdmin = new RoleStateCaretaker();
  9. stateAdmin.setMemento(lufi.saveState());// 将具体数据封装在了 Memento中
  10. // 大战Boss时,损耗严重
  11. lufi.fight();
  12. lufi.stateDisplay();
  13. // 恢复状态
  14. lufi.recoveryState(stateAdmin.getMemento());
  15. lufi.stateDisplay();
  16. }
  17. }

测试结果

与简单实现相同

总结

  • 把要保存的细节给封装在了 Memento 中,哪一天要更改保存细节也不用影响客户端。
  • 备忘录模式比较适用于功能比较复杂的,但需要维护或记录属性历史的类,或者需要保存的属性只是众多属性的一小部分时,Originator 可以根据保存的 Memento 信息还原到前一状态。
  • 如果在某个系统中使用命令模式时,需要实现命令的撤销功能,那么命令模式可以使用备忘录模式来存储可撤销操作的状态。
  • 使用备忘录可以把复杂的对象内部信息对其他的对象屏蔽起来。

原文链接:http://www.cnblogs.com/call-me-devil/p/11335226.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号