备忘录模式1_大话设计模式学习笔记18

Agatha ·
更新时间:2024-11-13
· 823 次阅读

大鸟给小菜的问题:

现编写一个代码,模拟游戏里的某个场景:游戏角色有生命力、攻击力、防御力等属性,他在打Boss前进行存档(满状态),然后去打Boss(被打成瓜皮)。体验完被虐的感受后,再读取之前满状态时的档案,又开始愉快地玩耍了。
ps:主要是体现存档、读档如何进行,而不是什么打斗场景。这是设计模式笔记!!!

1、小菜经过短暂的思考,快速地写出来他的答案: 直接来一个游戏角色类,生命力、攻击力、防御力用类的成员变量体现; 再编写几个方法:1、状态显示;2、角色属性初始化;3、战斗后角色属性变化 至于存档与读档的操作通过客户端来表示。

(1)游戏角色类

public class GameRole { private int vit; // 生命力 private int atk; // 攻击力 private int def; // 防御力 public void Vitality(int vit) { // 得到生命力的值 this.vit = vit; } public int Vitality() { // 修改生命力的值 return vit; } public void Attack(int atk) { // 得到攻击力的值 this.atk = atk; } public int Attack() { // 修改攻击力的值 return atk; } public void Defense(int def) { // 得到防御力的值 this.def = def; } public int Defense() { // 修改防御力的值 return def; } // 显示当前状态 public void StateDisplay() { System.out.println("角色当前状态:"); System.out.println("体力:" + this.vit); System.out.println("攻击力:" + this.atk); System.out.println("防御力:" + this.def); System.out.println("……"); } public void GetInitState() { // 状态初始化 this.vit = 100; this.atk = 100; this.def = 100; } public void Fight() { // 战斗后属性改变 this.vit = 0; this.atk = 0; this.def = 0; } }

(2)客户端代码

public class Memento1Demo { public static void main(String[] args) { // 大战Boss前 GameRole lixiaoyao = new GameRole(); lixiaoyao.GetInitState(); // 满状态 lixiaoyao.StateDisplay(); // 显示当前状态 // 进程存档 GameRole backup = new GameRole(); backup.Vitality(lixiaoyao.Vitality()); backup.Attack(lixiaoyao.Attack()); backup.Defense(lixiaoyao.Defense()); lixiaoyao.Fight(); // 大战 lixiaoyao.StateDisplay(); // 显示大战后的状态 // 读档 lixiaoyao.Vitality(backup.Vitality()); lixiaoyao.Attack(backup.Attack()); lixiaoyao.Defense(backup.Defense()); lixiaoyao.StateDisplay(); } }

(3)输出结果

角色当前状态: 体力:100 攻击力:100 防御力:100 …… 角色当前状态: 体力:0 攻击力:0 防御力:0 …… 角色当前状态: 体力:100 攻击力:100 防御力:100 …… 代码分析:

从功能实现来说,提出的要求都完成了。存档了,读档了,没别的遗漏。
但是从代码内容的结构来说,这编写极其糟糕!

首先,对于存档和读档来说,确实是从客户端发出这个操作,但请主要,这只能是发出请求,而不是执行这个请求。真正是在内部进行该操作,而上述代码就是犯了这个错!——简单来说,就是一点也不封闭!!! // 进程存档 GameRole backup = new GameRole(); backup.Vitality(lixiaoyao.Vitality()); backup.Attack(lixiaoyao.Attack()); backup.Defense(lixiaoyao.Defense()); // 读档 lixiaoyao.Vitality(backup.Vitality()); lixiaoyao.Attack(backup.Attack()); lixiaoyao.Defense(backup.Defense()); 其次,一点也不开发放!!!
例如,现在还有一个经验值(experience)的属性参数要加进去,安排小菜给的这份代码来说,那是不是需要加上: backup.Experience(lixiaoyao.Experience()); lixiaoyao.Experience(backup.Experience()); 修改方向:

客户端的调用在这份代码里的比重太大了,这就导致了一有什么改动,客户端也要进行修改,但客户端本来就不是需要经常修改的地方。套用一下课本的原话:显然,我们希望的是把这些“游戏角色”的存取状态封装起来,而且最好是封装在外部的类当中。
还有一点需要明白,客户端是发出操作请求的地方,不是进行具体操作内容的地方。

二、经过对“备忘录模式”的学习理解,小菜给出了他修改后的代码:

原创文章 71获赞 63访问量 3546 关注 私信 展开阅读全文
作者:大二_下



大话设计模式 备忘录模式 学习笔记 学习 备忘录 设计模式

需要 登录 后方可回复, 如果你还没有账号请 注册新账号
相关文章