Java设计模式之备忘录模式实现对象状态的保存和恢复
作者:.番茄炒蛋 发布时间:2023-08-28 15:22:27
介绍
备忘录模式(Memento Pattern)是一种行为型设计模式,它允许在不破坏封装性的前提下,捕获并保存一个对象的内部状态,并在之后可以恢复该对象到先前的状态.该模式的核心是备忘录(Memento)类,它储存了一个对象的内部状态.
在Java中,备忘录模式可以通过定义一个备忘录类来实现.备忘录类通常包含一个或多个私有字段来储存要保存的对象的内部状态.备忘录类还可以提供公共方法来获取和设置这些字段.原始对象可以使用备忘录类创建备忘录,并将其保存到历史记录中.在需要恢复对象的状态时,原始对象可以从历史记录中获取备忘录,并使用备忘录来恢复其状态.
在备忘录模式中,一般会涉及到以下三个角色:
Originator(发起人):它是要被保存状态的对象.它提供了创建备忘录和恢复备忘录的接口,允许其他对象获取其内部状态.
Memento(备忘录):它用于储存Originator内部状态得对象.备忘录可以根据Originator得需求来保存其内部状态,并且可以防止Originator以外得其他对象访问该状态.
Caretaker(管理者):它负责保存备忘录,并在需要时将其提供给Originator进行恢复,Caretaker可以储存多个备忘录,以及支持多次撤销操作.
在Java中实现备忘录模式时,一般会涉及到以上三个角色.其中Originator和Memento是必需的,Caretaker可以根据实际需要来选择是否实现.
实现
假设有一个游戏角色类Role,它有三个属性:attack(攻击力),defense(防御力)和hp(生命值).现在我们要实现一个备忘录模式,可以保存角色的状态,并在需要时恢复角色的状态.
备忘录类
@Data
public class Memento {
/**
* 攻击力
*/
private int attack;
/**
* 防御力
*/
private int defense;
/**
* 生命值
*/
private int hp;
public Memento(int attack, int defense, int hp) {
this.attack = attack;
this.defense = defense;
this.hp = hp;
}
}
发起人类
@Data
public class Role {
/**
* 攻击力
*/
private int attack;
/**
* 防御力
*/
private int defense;
/**
* 生命值
*/
private int hp;
public Role(int attack, int defense, int hp) {
this.attack = attack;
this.defense = defense;
this.hp = hp;
}
/**
* 将当前对象储存值Memento中
* @return
*/
public Memento save(){
return new Memento(attack,defense,hp);
}
/**
* 从memento中获取状态;并恢复到当前状态
* @param memento
*/
public void restore(Memento memento){
attack = memento.getAttack();
defense = memento.getDefense();
hp = memento.getHp();
}
}
管理者类
public class Caretaker {
private List<Memento> mementos = new ArrayList<>();
public void addMemento(Memento m){
mementos.add(m);
}
public Memento getMemento(int index){
return mementos.get(index);
}
}
测试
public class Demo {
public static void main(String[] args) {
Role role = new Role(100,50,20);
Caretaker caretaker = new Caretaker();
Memento memento = role.save();
caretaker.addMemento(memento);
// 攻击力+10
role.setAttack(role.getAttack()+10);
System.out.println(JSON.toJSONString(role));
// 恢复
role.restore(caretaker.getMemento(0));
System.out.println(JSON.toJSONString(role));
}
}
这是一个完整的备忘录模式的例子.在这个例子中,我们创建一个备忘录类Memento,它保存了角色的攻击力,防御力和生命值.我们还创建了一个角色类Role,它可以保存和恢复角色的状态.最后.我们创建了一个Caretaker类,它用于保存Memento对象.通过这些类的结合使用,我们实现了备忘录模式.
来源:https://blog.csdn.net/qq_43135259/article/details/129668905


猜你喜欢
- 使用@Provider注意事项(要点)1.在Mapper接口和@InsertProvider方法类中,不要使用重载,也就是说,不要使用方法名
- maven打包指定jdk的版本问题今天遇到个问题,项目中新写了一个接口,其中用到了lambda表达式,本地跑是没问题的,但提交到gitLab
- 一、简介前面介绍了平时用到的大多数的多线程的例子,但在实际开发中使用的线程往往是大量的和更为复杂的,这时,每次都创建线程、启动线程。从性能上
- jsoup 是一款 Java 的 HTML 解析器,可直接解析某个 URL 地址、HTML 文本内容。它提供了一套非常省力的 API,可通过
- 前言项目中检测人脸图片是否合法的功能,之前用的是百度的人脸识别接口,由于成本高昂不得不寻求替代方案。什么是opencv?OpenCV是一个基
- 本文实例讲述了Java利用反射自动封装成实体对象的方法。分享给大家供大家参考。具体分析如下:利用此方法的时候需要传递的参数的名称,必须以行号
- 在C#中,用于存储的结构较多,如:DataTable,DataSet,List,Dictionary,Stack等
- 一、Java语言本身也是多线程,回顾Java创建线程方式如下:1、继承Thread类,(Thread类实现Runnable接口),来个类图加
- 近日工作任务较轻,有空学习学习技术,遂来研究如果实现读写分离。这里用博客记录下过程,一方面可备日后查看,同时也能分享给大家(网上的资料真的大
- 区别一如果Mybatis Plus是扳手,那Mybatis Generator就是生产扳手的工厂。通俗来讲——MyBatis:一种操作数据库
- 一、HandlerThread的介绍及使用举例  
- Spring的HandlerMapping支持 * , * 必须实现HandlerInterceptor接口,此接口里面有下面3中方法:1.
- 详解json string转换为java bean及实例代码pom中添加如下两个库:<dependency> <
- 数字签名广泛用于保护PDF文档,可见数字签名在日常生活中是相当重要的。在这篇文章中我将与大家分享如何给PDF文件添加可见的数字签名。首先我下
- 前言C# 时间戳与 标准时间的转其实不难,但需要注意下,基准时间的问题。格林威治时间起点: 1970 年 1 月 1 日的 00:00:00
- 在MailSetting里的配置好邮件服务器,然后MailEntity里配置好要发送的邮件主体,最后使用MailServer里的方法Send
- Redis不仅可作为缓存服务器,还可以用作消息队列。它的列表类型天生支持用作消息队列。如下图所示:由于Redis的列表是使用双向链表实现的,
- 引入假定我们有两个项目:Cup 和 Water,其中 Cup 表示主项目,而 Water 表示子模块项目。其中 Cup 的远程仓库地址为 g
- 从今天开始写关于C#的系列文章,本篇文章主要讲解C#中的委托使用。委托其实就是一种数据类型,和int,string是一样的概念。如果要把一个
- 1、获取Class对象在 Java API 中,提供了获取 Class 类对象的三种方法:第一种,使用 Class.forName 静态方法