首页 > 其他分享 >如果再回到从前——备忘录模式

如果再回到从前——备忘录模式

时间:2024-09-28 10:22:15浏览次数:8  
标签:Originator 状态 游戏 保存 模式 备忘录 Memento 从前

文章目录

如果再回到从前——备忘录模式

如果再给我一次机会……

时间:5月6日18点  地点:小菜、大鸟住所的客厅  人物:小菜、大鸟

"小菜,今天上午看NBA了吗?"大鸟问道。

“没有,不过结果倒是在网上第一时间就知道了。”

“是呀,最后一分钟的失误,就等于输掉了整个赛季。”

"如果任何一人能抓到两个篮板中的一个,结果可能完全不是这样。真是遗憾呀。"小菜感慨道。

“很多时候我们做了件事后,却又后悔。这就是人类内心软弱的一面。时间不能倒流,不管怎么样人生是无法回到从前的,但是软件就不一样了。还记得玩一些单机的PC游戏的时候吗,通常我都是在打大Boss之前,先保存一个进度,然后如果通关失败了,我可以再返回刚才那个进度来恢复原来的状态,从头来过。从这点上说,我们比姚明强。”

“哈,这其中的原理是不是就是把当前的游戏状态的各种参数存储,以便恢复时读取呢?”

“是的,通常这种保存都是存在磁盘上了,以便日后读取。但对于一些更为常规的应用,比如我们下棋时通常悔棋、编写文档时需要撤销、查看网页时需要后退,这些相对频繁而简单的恢复并不需要存在磁盘中,只要将保存在内存中的状态恢复一下即可。”

“嗯,这是更普通的应用,很多开发中都会用到。”

“那我简单说个场景,你想想看怎么用代码实现。游戏的某个场景,一游戏角色有生命力、攻击力、防御力等数据,在打Boss前和后一定会不一样的,我们允许玩家如果感觉与Boss决斗的效果不理想可以让游戏恢复到决斗前。”

在这里插入图片描述

在这里插入图片描述

“好的,我试试看。”

游戏存进度

游戏角色类,用来存储角色的生命力、攻击力、防御力的数据。

在这里插入图片描述

客户端调用时:

在这里插入图片描述

“小菜,这样的写法,确实是实现了我的要求,但是问题也确实多多。”

“哈,你的经典理论,代码无错未必优。说吧,我有心理准备。”

“问题主要在于这客户端的调用。下面这一段有问题,因为这样写就把整个游戏角色的细节暴露给了客户端,你的客户端的职责就太大了,需要知道游戏角色的生命力、攻击力、防御力这些细节,还要对它进行’备份’。以后需要增加新的数据,例如增加’魔法力’或修改现有的某种力,例如’生命力’改为’经验值’,这部分就一定要修改了。同样的道理也存在于恢复时的代码。”

在这里插入图片描述

“显然,我们希望的是把这些’游戏角色’的存取状态细节封装起来,而且最好是封装在外部的类当中。以体现职责分离。”

备忘录模式

“所以我们需要学习一个新的设计模式——备忘录模式。”

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

备忘录模式(Memento)结构图:

在这里插入图片描述

■ Originator(发起人):负责创建一个备忘录Memento,用以记录当前时刻它的内部状态,并可使用备忘录恢复内部状态。Originator可根据需要决定Memento存储Originator的哪些内部状态。

■ Memento(备忘录):负责存储Originator对象的内部状态,并可防止Originator以外的其他对象访问备忘录Memento。备忘录有两个接口,Caretaker只能看到备忘录的窄接口,它只能将备忘录传递给其他对象。Originator能够看到一个宽接口,允许它访问返回到先前状态所需的所有数据。

■ Caretaker(管理者):负责保存好备忘录Memento,不能对备忘录的内容进行操作或检查。

“就刚才的例子,'游戏角色’类其实就是一个Originator,而你用了同样的’游戏角色’实例’备份’来做备忘录,这在当需要保存全部信息时,是可以考虑的,而用clone的方式来实现Memento的状态保存可能是更好的办法,但是如果是这样的话,使得我们相当于对上层应用开放了Originator的全部(public)接口,这对于保存备份有时候是不合适的。”

“那如果我们不需要保存全部的信息以备使用时,怎么办?”

“哈,对的,这或许是更多可能发生的情况,我们需要保存的并不是全部信息,而只是部分,那么就应该有一个独立的备忘录类Memento,它只拥有需要保存的信息的属性。”

备忘录模式基本代码

发起人(Originator)类:

在这里插入图片描述

管理者(Caretaker)类:

在这里插入图片描述

“哈,我明白了,这当中就是把要保存的细节给封装在了Memento中了,哪一天要更改保存的细节也不用影响客户端了。那么这个备忘录模式都用在一些什么场合呢?”

“Memento模式比较适用于功能比较复杂的,但需要维护或记录属性历史的类,或者需要保存的属性只是众多属性中的一小部分时,Originator可以根据保存的Memento信息还原到前一状态。”

“我记得好像命令模式也有实现类似撤销的作用?”

“哈,小子记性不错,如果在某个系统中使用命令模式时,需要实现命令的撤销功能,那么命令模式可以使用备忘录模式来存储可撤销操作的状态[DP]。有时一些对象的内部信息必须保存在对象以外的地方,但是必须要由对象自己读取,这时,使用备忘录可以把复杂的对象内部信息对其他的对象屏蔽起来[DP],从而可以恰当地保持封装的边界。”

“我感觉**可能最大的作用还是在当角色的状态改变的时候,有可能这个状态无效,这时候就可以使用暂时存储起来的备忘录将状态复原[DP]**这个作用吧?”

“说得好,这当然是最重要的作用了。”

“明白,我学会了。”

“别急,你还没有把你刚才的代码改成备忘录模式的。”

“啊,你就不打算饶过我。等着,看我来拿满分。”

游戏进度备忘

在这里插入图片描述

游戏角色类:

在这里插入图片描述

角色状态存储箱类:

在这里插入图片描述

客户端代码:

在这里插入图片描述

“看看,能不能得满分?我查了好几遍了。”

“不错,写得还行。你要注意,备忘录模式也是有缺点的,角色状态需要完整存储到备忘录对象中,如果状态数据很大很多,那么在资源消耗上,备忘录对象会非常耗内存。”

“嗯,明白。所以也不是用得越多越好。”

"小子,以后打游戏要记着用备忘录哦。"大鸟不忘提醒一句。

"哈,我一定会这样。"小菜开始装着深沉地说,“曾经有一个精彩的游戏摆在我的面前,但是我没有好好珍惜。等到死于Boss手下的时候才后悔莫及,尘世间最痛苦的事莫过于此。如果上天可以给我一个机会再来一次的话,我会对你说三个字,‘存进度’。如果非要把这个进度加上一个保险,我希望是刻成光盘,流传万年!”

如果对你有帮助,就一键三连呗(关注+点赞+收藏),我会持续更新更多干货~~

标签:Originator,状态,游戏,保存,模式,备忘录,Memento,从前
From: https://blog.csdn.net/m0_63526467/article/details/142611689

相关文章

  • 开源链动2+1模式AI智能名片小程序源码:放大特色,构建独特竞争力
    摘要:本文探讨在当今社会背景下,开源链动2+1模式AI智能名片小程序源码如何通过坚持与众不同来构建独特竞争力。在信息传播便捷但个体易同质化的时代,拥有特色是脱颖而出的关键,而这种模式下的小程序源码具有独特的发展潜力。一、引言当今社会,一方面互联网使信息传播便捷高效,另一......
  • 多线程下单例模式延迟初始化的实现
    多线程下单例模式延迟初始化的实现前言synchronized修饰方法双重检查锁定双重检查锁定的问题基于volatile的双重锁定方案类初始化总结前言在程序开发中,存在一些开销较高的资源,例如数据库连接等,我们使用单例模式保证其唯一并且进行延迟初始化,只有当使用的时候才进行......
  • keepalived+nginx实现高可用的案例详解(主主模式)
    文章目录前言keepalived主备模式和主主模式有什么区别1.主备模式(Master-BackupMode)2.主主模式(Active-ActiveMode或DualMasterMode)主备模式vs主主模式的区别总结:环境案例实现具体步骤ngx1ngx2验证前言keepalived主备模式和主主模式有什么区别Keepali......
  • RabbitMQ五种工作模式的代码具体实现(代码简单易懂)(一)
    一、简单队列模式:直接把消息发送给队列,且队列只有一个消费者。使用的是Rabbitmq默认的交换机。生产者部分:<!--amqp依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</art......
  • 农村生活污水治理推荐技术模式
    前 言为扎实推进我国农村生活污水治理,改善人居环境,建设宜居宜业和美乡村,遴选了一批较为成熟的农村生活污水治理技术模式。主要遵循以下原则:生态循环、利用优先。牢固树立绿色发展理念,结合农田灌溉回用、生态保护修复、环境景观建设等,鼓励农村黑水、灰水分别处理回用,鼓励污......
  • 建造者模式与lombok
    当一个类的参数过多,并且大部分时候这些参数都是可选参数的时候,我们就会考虑使用建造者模式lombok插件中提供了Builder方法@Data@BuilderpublicclassCase{privateStringname;privateStringdesc;}编译后的case类publicclassCase{privateString......
  • Java设计模式6 - 策略模式
    策略模式策略模式的用意是针对一组算法,将每一个算法封装到具有共同接口的独立类中,从而使得它们可以相互替换。策略模式使得算法可以在不影响到客户端的情况下发生变化。 策略模式的结构策略模式是对算法的包装,是把使用算法的责任和算法本身分开。策略模式通常是把一系列的算法包装......
  • JMeter的CLI模式(非GUI模式)常用命令
    JMeter的CLI模式(非GUI模式)常用命令ApacheJMeter是一款强大的开源性能测试工具,它支持图形用户界面(GUI)模式和非图形用户界面(CLI,即CommandLineInterface)模式。在实际的性能测试工作中,CLI模式因其能够减少资源消耗和提高测试效率而备受青睐。本文将详细介绍JMeter在CLI模式下的常......
  • Java设计模式5 - 原型模式
    原型模式原型模式属于对象的创建模式,通过给出一个原型对象来指明所有创建的对象的类型,然后用复制这个原型对象的办法创建出更多同类型的对象,这就是原型模式的用意。 原型模式结构原型模式要求对象实现一个可以克隆机身的接口,这样就可以通过复制一个实例对象本身来创建一个新的实例......
  • 建造者模式
    简介建造者模式(BuilderPattern)将一个复杂对象的构建过程与它的表示分离,使得同样的构建过程可以创建不同的表示,属于创建型设计模式。通用模板创建产品类:要创建的产品类对象。//产品类publicclassProduct{//产品组成部件1publicStringpart1;//......