Go和Java实现备忘录模式

Go和Java实现备忘录模式

下面通过一个保存游戏进度的案例来说明备忘录模式的使用。

1、备忘录模式

备忘录模式保存一个对象的某个状态,以便在适当的时候恢复对象。备忘录模式属于行为型模式。

  • 意图:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。

  • 主要解决:所谓备忘录模式就是在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个

    状态,这样可以在以后将对象恢复到原先保存的状态。

  • 何时使用:很多时候我们总是需要记录一个对象的内部状态,这样做的目的就是为了允许用户取消不确定或者

    错误的操作,能够恢复到他原先的状态,使得他有"后悔药"可吃。

  • 如何解决:通过一个备忘录类专门存储对象状态。

  • 关键代码:客户不与备忘录类耦合,与备忘录管理类耦合。

  • 应用实例: 1、后悔药。 2、打游戏时的存档。 3、Windows 里的 ctrl + z。 4、IE 中的后退。 5、数据库的事

    务管理。

  • 优点:1、给用户提供了一种可以恢复状态的机制,可以使用户能够比较方便地回到某个历史的状态。 2、实

    现了信息的封装,使得用户不需要关心状态的保存细节。

  • 缺点:消耗资源。如果类的成员变量过多,势必会占用比较大的资源,而且每一次保存都会消耗一定的内存。

  • 使用场景:1、需要保存/恢复数据的相关状态场景。 2、提供一个可回滚的操作。

  • 注意事项:1、为了符合迪米特原则,还要增加一个管理备忘录的类。 2、为了节约内存,可使用原型模式+备

    忘录模式。

  • 适用性:

    必须保存一个对象在某一个时刻的(部分)状态,这样以后需要时它才能恢复到先前的状态。

    如果一个用接口来让其它对象直接得到这些状态,将会暴露对象的实现细节并破坏对象的封装性。

2、Go实现备忘录模式

package memento// ========== 角色状态存储箱RoleStateMemento ==========
// 备忘录存储原发器对象的内部状态
type RoleStateMemento struct {// 生命力vit int// 攻击力atk int// 防御力def int
}func NewRoleStateMemento(vit, atk, def int) RoleStateMemento {return RoleStateMemento{vit: vit,atk: atk,def: def,}
}
package mementoimport "fmt"// ========== 游戏角色GameRole ==========
// 原发器创建一个备忘录,用以记录当前时刻的内部状态,使用备忘录恢复内部状态
type GameRole struct {// 生命力vit int// 攻击力atk int// 防御力def int
}// 状态显示
func (gameRole *GameRole) StateDisplay() {fmt.Println("角色当前状态: ")fmt.Println("体力: ", gameRole.vit)fmt.Println("攻击力: ", gameRole.atk)fmt.Println("防御力: ", gameRole.def)
}// 获得初始状态
func (gameRole *GameRole) GetInitState() {gameRole.vit = 100gameRole.atk = 100gameRole.def = 100
}// 战斗
func (gameRole *GameRole) Fight() {gameRole.vit = 0gameRole.atk = 0gameRole.def = 0
}// 保存角色状态
func (gameRole *GameRole) SaveState() RoleStateMemento {return NewRoleStateMemento(gameRole.vit, gameRole.atk, gameRole.def)
}// 恢复角色状态
func (gameRole *GameRole) RecoveryState(roleStateMemento RoleStateMemento) {gameRole.vit = roleStateMemento.vitgameRole.atk = roleStateMemento.atkgameRole.def = roleStateMemento.def
}
package memento// ========== 角色状态管理者RoleStateCaretaker ==========
// 负责保存好备忘录,不能对备忘录的内部进行操作或检查
type RoleStateCaretaker struct {roleStateMemento RoleStateMemento
}func (roleStateCaretaker *RoleStateCaretaker) GetRoleStateMemento() RoleStateMemento {return roleStateCaretaker.roleStateMemento
}func (roleStateCaretaker *RoleStateCaretaker) SetRoleStateMemento(roleStateMemento RoleStateMemento) {roleStateCaretaker.roleStateMemento = roleStateMemento
}
package mainimport . "proj/memento"func main() {gameRole := GameRole{}gameRole.GetInitState()gameRole.StateDisplay()// 保存进度roleStateCaretaker := RoleStateCaretaker{}roleStateCaretaker.SetRoleStateMemento(gameRole.SaveState())// 进行战斗gameRole.Fight()gameRole.StateDisplay()// 恢复之前状态gameRole.RecoveryState(roleStateCaretaker.GetRoleStateMemento())gameRole.StateDisplay()}
# 程序输出
角色当前状态: 
体力:  100
攻击力:  100
防御力:  100
角色当前状态:
体力:  0
攻击力:  0
防御力:  0
角色当前状态:
体力:  100
攻击力:  100
防御力:  100

3、Java备忘录模式

package com.memento;// ========== 角色状态存储箱RoleStateMemento ==========
// 备忘录存储原发器对象的内部状态
public class RoleStateMemento {// 生命力private int vit;// 攻击力private int atk;// 防御力private int def;public RoleStateMemento(int vit,int atk,int def){this.vit = vit;this.atk = atk;this.def = def;}public int getVit() {return vit;}public void setVit(int vit) {this.vit = vit;}public int getAtk() {return atk;}public void setAtk(int atk) {this.atk = atk;}public int getDef() {return def;}public void setDef(int def) {this.def = def;}}
package com.memento;// ========== 游戏角色GameRole ==========
// 原发器创建一个备忘录,用以记录当前时刻的内部状态,使用备忘录恢复内部状态
public class GameRole {// 生命力private int vit;// 攻击力private int atk;// 防御力private int def;public int getVit() {return vit;}public void setVit(int vit) {this.vit = vit;}public int getAtk() {return atk;}public void setAtk(int atk) {this.atk = atk;}public int getDef() {return def;}public void setDef(int def) {this.def = 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(){this.vit = 0;this.atk =  0;this.def = 0;}// 保存角色状态public RoleStateMemento saveState(){return new RoleStateMemento(vit,atk,def);}// 恢复角色状态public void recoveryState(RoleStateMemento roleStateMemento){this.vit = roleStateMemento.getVit();this.atk = roleStateMemento.getAtk();this.def = roleStateMemento.getDef();}
}
package com.memento;// ========== 角色状态管理者RoleStateCaretaker ==========
// 负责保存好备忘录,不能对备忘录的内部进行操作或检查
public class RoleStateCaretaker {private RoleStateMemento roleStateMemento;public RoleStateMemento getRoleStateMemento() {return roleStateMemento;}public void setRoleStateMemento(RoleStateMemento roleStateMemento) {this.roleStateMemento = roleStateMemento;}
}
package com.memento;public class Test {public static void main(String[] args) {GameRole gameRole = new GameRole();gameRole.getInitState();gameRole.stateDisplay();// 保存进度RoleStateCaretaker roleStateCaretaker = new RoleStateCaretaker();roleStateCaretaker.setRoleStateMemento(gameRole.saveState());// 进行战斗gameRole.fight();gameRole.stateDisplay();// 恢复之前状态gameRole.recoveryState(roleStateCaretaker.getRoleStateMemento());gameRole.stateDisplay();}
}
# 程序输出
角色当前状态: 
体力: 100
攻击力: 100
防御力: 100
角色当前状态: 
体力: 0
攻击力: 0
防御力: 0
角色当前状态: 
体力: 100
攻击力: 100
防御力: 100

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/65885.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【C++】学习STL中的stack和queue

❤️前言 今天这篇博客的内容主要关于STL中的stack、queue和priority_queue三种容器。 正文 stack和queue的使用方式非常简单,我们只要根据之前学习数据结构的经验和文档介绍就可以轻松上手。于是我们直接开始对它们的模拟实现。 stack和queue的模拟实现 stack和q…

大数据HBase学习圣经:一本书实现HBase学习自由

学习目标:三栖合一架构师 本文是《大数据HBase学习圣经》 V1版本,是 《尼恩 大数据 面试宝典》姊妹篇。 这里特别说明一下:《尼恩 大数据 面试宝典》5个专题 PDF 自首次发布以来, 已经汇集了 好几百题,大量的大厂面试…

Leetcode98. 验证二叉搜索树

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台 给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。 有效 二叉搜索树定义如下: 节点的左子树只包含 小于 当前节点的数。节点的右子树只包含 大于 当前节点的数。…

实际并行workers数量不等于postgresql.conf中设置的max_parallel_workers_per_gather数量

1 前言 本文件的源码来自PostgreSQL 14.5,其它版本略有不同并行workers并不能显箸提升性能。个人不建议使用并行worker进程,大多数情况下采用postgresql.conf默认配置即可。 PostgreSQL的并行workers是由compute_parallel_worker函数决定的&#xff0c…

Java-Optional类

概述 Optional是JAVA 8引入的一个类,用于处理可能为null的值。 利用Optional可以减少代码中if-else的判断逻辑,增加代码的可读性。且可以减少空指针异常的发生,增加代码的安全性。 常用的方法 示例 代码 public class OptionalTest {pub…

ChatGPT在航空航天工程和太空探索中的潜在应用如何?

ChatGPT在航空航天工程和太空探索领域具有广泛的潜在应用。这些应用可以涵盖从设计和模拟到任务控制和数据分析的多个方面。本文将探讨ChatGPT在航空航天和太空探索中的各种可能应用,包括设计优化、任务规划、智能导航、卫星通信、数据分析和太空探测器运行。 ### …

[深度学习]大模型训练之框架篇--DeepSpeed使用

现在的模型越来越大,动辄几B甚至几百B。但是显卡显存大小根本无法支撑训练推理。例如,一块RTX2090的10G显存,光把模型加载上去,就会OOM,更别提后面的训练优化。 作为传统pytorch Dataparallel的一种替代,D…

基于java+springboot+vue的交流互动系统-lw

​ 系统介绍: 随着现在网络的快速发展,网上管理系统也逐渐快速发展起来,网上管理模式很快融入到了许多企业的之中,随之就产生了“交流互动系统”,这样就让交流互动系统更加方便简单。 对于本交流互动系统的设计来说&a…

继承【C++】

文章目录 继承的概念继承的定义继承方式和访问限定符继承基类成员访问方式的变化 默认继承方式 基类和派生类对象赋值转换继承中的作用域派生类的默认成员函数继承与友元静态成员菱形继承及菱形虚拟继承继承的方式 菱形虚拟继承菱形虚拟继承原理 继承的概念 继承(inheritance)…

java基础-----第六篇

系列文章目录 文章目录 系列文章目录一、HashMap和HashTable有什么区别?其底层实现是什么?二、ConcurrentHashMap原理,jdk7和jdk8版本的区别一、HashMap和HashTable有什么区别?其底层实现是什么? 1.区别 : (1)HashMap方法没有synchronized修饰,线程非安全,HashTable…

【Unity笔记】TimeLine的详细使用介绍

文章目录 前言素材一、timeline基础介绍1. 打开timeline轨道面板2. 创建TimeLine轨道3. Timeline常用轨道4. 修改Timeline单位5. 锁定界面 二、timeline的通用轨道使用三、Cinemeachine虚拟相机结合Timeline实现场景移动四、DialogueTrack:自定义的对话轨道(自己编写…

swagger 接口测试,用 python 写自动化时该如何处理?

在使用Python进行Swagger接口测试时,可以使用requests库来发送HTTP请求,并使用json库和yaml库来处理响应数据。以下是一个简单的示例代码: import requests import json import yaml# Swagger API文档地址和需要测试的接口路径 swagger_url …

如何处理 Flink 作业中的数据倾斜问题?

分析&回答 什么是数据倾斜? 由于数据分布不均匀,造成数据大量的集中到一点,造成数据热点。 举例:一个 Flink 作业包含 200 个 Task 节点,其中有 199 个节点可以在很短的时间内完成计算。但是有一个节点执行时间…

设计模式之原型模式

文章目录 概述克隆羊问题传统方式解决克隆羊问题传统的方式的优缺点原型模式原理结构图-uml 类图原理结构图说明 原型模式解决克隆羊问题的应用实例原型模式在Spring框架中的应用深入讨论-浅拷贝和深拷贝浅拷贝的介绍深拷贝基本介绍深拷贝应用实例注意事项 概述 原型模式&…

Linux - Docker 安装使用 常用命令 教程

Docker 官方文档地址: Get Started | Docker 中文参考手册: https://docker_practice.gitee.io/zh-cn/ 1.什么是 Docker 1.1 官方定义 最新官网首页 # 1.官方介绍 - We have a complete container solution for you - no matter who you are and where you are on your contain…

Linux学习之NAS服务器搭建

NAS是Network Attached Storage的缩写,也就是网络附属存储。可以使用自己已经不怎么使用的笔记本搭建一台NAS服务器。 fdisk -l可以看一下各个磁盘的状态。 可以看到有sda、sdb、sdc和sdd等四块硬盘。 lvs、vgs和pvs结合起来看,sdb和sdc没有被使用。 …

Mac“其他文件”存放着什么?“其他文件”的清理方法

很多Mac用户在清理磁盘空间时发现,内存占用比例比较大的除了有iCloud云盘、应用程序、影片、音频、照片等项目之外,还有一个“其他文件”的项目磁盘占用比也非常大,想要清理却无从下手。那么Mac“其他文件”里存放的是什么文件?我…

文本标注技术方案(NLP标注工具)

Doccano doccano 是一个面向人类的开源文本注释工具。它为文本分类、序列标记和序列到序列任务提供注释功能。您可以创建用于情感分析、命名实体识别、文本摘要等的标记数据。只需创建一个项目,上传数据,然后开始注释。您可以在数小时内构建数据集。 支持…

并发下的Map常见面试题

HashMap 和 HashTable 有什么区别?java中的另一个线程安全的与HashMap极其类似的类是什么?同样是线程安全,它与HashTable在线程同步上有什么不同?HashMap 与 ConcurrentHashMap的区别?为什么 ConcurrentHashMap 比 Has…

开源且强大的网络嗅探分析工具——Wireshark

Wireshark是一款强大的开源网络协议分析工具,旨在帮助用户深入了解网络通信的细节。通过捕获、解析和展示网络数据包,Wireshark能够帮助工程师诊断问题、优化性能,以及解决各种网络难题。无论是深入分析还是快速调试,Wireshark都是…