设计模式之备忘录模式

news2024/11/15 15:49:49

Memento design pattern

备忘录模式的概念、备忘录模式的结构、备忘录模式的优缺点、备忘录模式的使用场景、备忘录模式的实现示例、备忘录模式的源码分析


1、备忘录模式的概念

  备忘录模式,又称快照模式,即在不破坏封装的前提下,获取并保存一个对象某一时刻的内部状态,以便以后恢复它。编辑器中的 Ctrl + Z、后退、数据库事务回滚、游戏存档、后悔药等都是备忘录模式的典型应用。

2、备忘录模式的结构

  • 拥有者/创建者:即备忘录的拥有者或创建者,也可理解为备忘录中记录的状态所对应的对象。并提供保存状态、恢复状态的行为。
  • 备忘录:负责存储创建者的内部状态,并在需要的时候将状态提供给创建者。
  • 管理者:即备忘录的管理者,负责维护和存储备忘录,并提供添加备忘录、获取备忘录的行为。

memento-class

3、备忘录模式的优缺点

  • 优点:
    • 提供了一种可以恢复状态的机制,使得用户在有需要的时候可以将数据恢复到某个历史状态。
    • 实现了内部状态的封装。除了创建它的用户外,其它对象都不能够访问这些状态信息。
    • 简化了创建者类,创建者类不需要管理和维护其内部的各个状态,其所有状态信息都有备忘录的管理负责维护,符合单一职责原则。
  • 缺点:
    • 资源消耗过大。若要保存的内部状态信息过多或过频繁,则会导致占用较大的内存资源。

4、备忘录模式的使用场景。

  • 需要保存与恢复数据的场景,如游戏中的存档功能。
  • 需要提供一个可回滚操作的场景,如 Ctrl + Z、数据库事务回滚等。

5、备忘录模式的实现示例

创建者:

public class Hero {

    private Integer health;

    private Integer attack;

    public Hero(Integer health, Integer attack) {
        this.health = health;
        this.attack = attack;
    }

    /**
     * 保存状态
     * @return
     */
    public HeroMemento saveState() {
        return new HeroMemento(this.health, this.attack);
    }

    /**
     * 恢复状态
     * @param heroMemento
     */
    public void recoverState(HeroMemento heroMemento) {
        this.health = heroMemento.getHealth();
        this.attack = heroMemento.getAttack();
    }

    public Integer getHealth() {
        return health;
    }

    public void setHealth(Integer health) {
        this.health = health;
    }

    public Integer getAttack() {
        return attack;
    }

    public void setAttack(Integer attack) {
        this.attack = attack;
    }

    /**
     * 展示当前状态
     */
    public void display() {
        System.out.println("health = " + this.getHealth() + " attack = " + this.getAttack());
    }
}

备忘录:

public class HeroMemento {

    private Integer health;

    private Integer attack;

    public HeroMemento(Integer health, Integer attack) {
        this.health = health;
        this.attack = attack;
    }

    public Integer getHealth() {
        return health;
    }

    public Integer getAttack() {
        return attack;
    }

    /**
     * 获取状态
     */
    public String display() {
        return "health = " + this.getHealth() + " attack = " + this.getAttack();
    }
}

管理者:

public class CareTaker {

    private List<HeroMemento> mementos;

    public CareTaker() {
        this.mementos = new ArrayList<>();
    }

    /**
     * 添加状态
     * @param heroMemento
     */
    public void addMemento(HeroMemento heroMemento) {
        this.mementos.add(heroMemento);
    }

    /**
     * 获取状态
     * @param index
     * @return
     */
    public HeroMemento getMemento(Integer index) {
        return this.mementos.get(index);
    }

    /**
     * 展示备忘录中所有状态
     */
    public void display() {
        HeroMemento heroMemento;
        for (int i = 0; i < this.mementos.size(); i++) {
            heroMemento = this.mementos.get(i);
            System.out.println("时刻 " + i + " 状态 " + heroMemento.display());
        }
    }
}

测试:

public class MementoTest {

    public static void main(String[] args) {
        CareTaker careTaker = new CareTaker();

        Hero hero = new Hero(100, 100);
        careTaker.addMemento(hero.saveState());

        hero.setHealth(80);
        hero.setAttack(120);
        careTaker.addMemento(hero.saveState());

        hero.setHealth(60);
        hero.setAttack(140);
        careTaker.addMemento(hero.saveState());

        System.out.println("备忘录中所有状态");
        careTaker.display();
        System.out.println();

        System.out.println("创建者当前状态");
        hero.display();
        System.out.println();

        System.out.println("恢复到某一时刻的状态");
        hero.recoverState(careTaker.getMemento(1));
        hero.display();
    }
}

测试结果:

备忘录中所有状态
时刻 0 状态 health = 100 attack = 100
时刻 1 状态 health = 80 attack = 120
时刻 2 状态 health = 60 attack = 140

创建者当前状态
health = 60 attack = 140

恢复到某一时刻的状态
health = 80 attack = 120

6、备忘录模式的源码分析

404

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

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

相关文章

【数电】Simulation Test 模拟测试

一、 选择题&#xff1a;&#xff08;共20分&#xff0c;每小题2分&#xff09; 1、逻辑函数的所有最小项之和等于多少&#xff1f; A. 0 B. 1 C. 0或1 D. 任意值 2、与非门的多余输入端应如何处理&#xff1f;…

MySQL面试常问问题(基础) —— 赶快收藏

目录 1. 什么是内连接、外连接、交叉连接、笛卡尔积呢&#xff1f; 2. 那MySQL 的内连接、左连接、右连接有有什么区别&#xff1f; 3.说一下数据库的三大范式&#xff1f; 4.varchar与char的区别&#xff1f; 5.blob和text有什么区别&#xff1f; 6.DATETIME和TIMESTAMP…

SCSS学习笔记

文章目录1.安装scss2.选择器嵌套3.属性嵌套4.父选择器&5.变量5.1变量的规范5.2变量的作用域5.3给变量设置默认值(!default)6数据类型7.运算符8.插值语法9.流程控制语句9.1 条件语句9.2循环语句9.2.1for9.2.2each9.2.3while10import10.1引入scss不编译10.2嵌套引入scss11.mi…

【软件测试】概念篇

目录 一、需求 1.1用户需求 1.2软件需求 1.3需求的重要性 二、测试用例 三、BUG 3.1什么是BUG 3.2如何描述一个BUG 4.3BUG优先级 四、软件开发模型 4.1软件生命周期 4.2开发模型 定义&#xff1a;软件测试就是一系列活动&#xff0c;这些活动是为了评估一个程序或者…

新店速递 | IU酒店带您领略“东方古罗马”

淄博&#xff0c;位处鲁中&#xff0c;是黄河三角洲生态经济和蓝色经济区的交汇处。四季分明的气候造就了这座齐国故都的生态多样性&#xff0c;南高北低的地理位置使其峻岭平原兼具&#xff0c;鲁中的位置又赋予他交通枢纽的重要性。这里历史气息浓厚&#xff0c;社会文化自由…

中文语法纠错全国大赛获奖分享:基于多轮机制的中文语法纠错

中文语法纠错任务旨在对文本中存在的拼写、语法等错误进行自动检测和纠正&#xff0c;是自然语言处理领域一项重要的任务。同时该任务在公文、新闻和教育等领域都有着落地的应用价值。但由于中文具有的文法和句法规则比较复杂&#xff0c;基于深度学习的中文文本纠错在实际落地…

新能源汽车市场渗透率不断提高,锂电设备需求空间较大

根据观研报告网发布的《中国新能源汽车行业发展深度研究与投资趋势调研报告&#xff08;2022-2029年&#xff09;》显示&#xff0c;近年来&#xff0c;随着各国开启能源转型&#xff0c;在汽车领域&#xff0c;由于电动汽车具有高效节能、零排放等优点&#xff0c;已逐渐成为汽…

配置小型公司网络WLAN基本业务(AC通过三层口管理AP)

组网需求&#xff1a; 某小型企业由于业务需要&#xff0c;希望员工能在企业内部随时随地的访问Internet&#xff0c;进行移动办公。该企业部署了一台AR路由器作为出口网关&#xff0c;希望同时在AR路由器上部署WLAN功能&#xff0c;为企业员工提供无线网络接入服务&#xff0c…

JDK,JRE,JVM的作用及关系

1.定义JDK(Java Development Kit): 是Java语言的软件开发工具包&#xff0c;内部包含了代码的编译工具和运行工具。JRE(Java Runtime Environment): 指Java运行时环境&#xff0c;包含java虚似机、以及核心类库(java帮我们写好的程序)等java运行所需的东西。JVM(Java Virtual M…

必须要学习的源码--ConcurrentHashMap

并发安全的集合&#xff1f; 并发不安全的集合 在 Java 中&#xff0c;有一些集合是不安全的&#xff0c;因为它们不是线程安全的。这意味着如果多个线程同时访问这些集合&#xff0c;那么它们可能会出现不可预料的行为。 Java 中的并发不安全的集合包括&#xff1a; ArrayLi…

花房集团上市,走向元宇宙新征程

12月12日&#xff0c;花房集团在港交所成功上市&#xff0c;首日便受到追捧&#xff0c;当日最高涨幅达28.75%。 继360、360数科、鲁大师后&#xff0c;这是“红衣教主”周鸿祎收获的第四个IPO。 花房集团作为直播界元老之一&#xff0c;两年内三次申请IPO&#xff0c;终于在…

(GCC)STM32进阶详解之栈回溯

接上一篇&#xff1a; 函数调用 由上一篇大概了解了函数是如何被调用&#xff0c;中断或者说异常又是如何被调用&#xff0c;而这一篇相当于上一篇知识的一个应用&#xff0c;也是上一篇遗留的思考&#xff0c;即在hardfault中如何判断是从何处触发这个异常的。本来打算自己写…

GO09:整型、浮点、字符类型的介绍和使用细节

基本类型的使用 基本介绍 3.8整数的各个类型 func main(){var i int 1 fmt.Println("i", i) var j int8 127 fmt.Println("j", j) }int的无符号的类型&#xff1a; 整型的使用细节 一、Golang各整数部分&#xff1a;有符号和无符号&#xff0c;int u…

信而泰RENIX 802.1ag功能介绍-网络测试仪实操

一、EOAM概述​ 1.以太网​ 1.1以太网优点​ 简单易用​ 价格低廉​ 高拓展性​ 大势所趋&#xff0c;一统天下​ 1.2以太网缺点​ 可管理性差​ 定位故障手段少​ 定位故障速度慢​ 维护成本高​ 2.以太网OAM​ ■EOAM​ 为运营商服务​ 提高以太网可靠性、可维…

非零基础自学Golang 第15章 Go命令行工具 15.6 性能分析 15.6.2 通过文件方式 15.6.3 通过HTTP方式 15.7 小结

非零基础自学Golang 文章目录非零基础自学Golang第15章 Go命令行工具15.6 性能分析15.6.2 通过文件方式15.6.3 通过HTTP方式15.7 小结第15章 Go命令行工具 15.6 性能分析 15.6.2 通过文件方式 为了能分析Go程序的性能&#xff0c;我们需要在程序中导入runtime/pprof来生成性…

飞鹤揭榜“十四五”项目,牵头研制新一代婴配粉

12月22日&#xff0c;在“鲜萃活性营养&#xff0c;更适合中国宝宝体质”中国飞鹤60周年战略升级发布会上&#xff0c;飞鹤对外公布&#xff0c;其牵头申报的——“基于中国母乳研究的新一代婴配乳粉制造技术研究与示范”项目成功获批。 这是继去年飞鹤与江南大学、大连工业大…

大数据基础平台搭建-(二)Hadoop集群搭建

大数据基础平台搭建-&#xff08;二&#xff09;Hadoop集群搭建 大数据平台系列文章&#xff1a; 1、大数据基础平台搭建-&#xff08;一&#xff09;基础环境准备 2、大数据基础平台搭建-&#xff08;二&#xff09;Hadoop集群搭建 大数据平台是基于Apache Hadoop_3.3.4搭建的…

不同存储资源的应用场景及优缺点介绍

容器应用应当根据应用系统的特点&#xff0c;综合考虑容器应用对存储类型、存储性能及数据高可用等方面的要求&#xff0c;选择最适合的存储资源类型。常见的存储资源应用场景包括三类&#xff1a;将存储挂载在外部宿主机上、将存储放置于容器内部和使用外部共享存储。下面对每…

MySQL面试常问问题(数据库架构+存储引擎) —— 赶快收藏

目录 1.说说 MySQL 的基础架构? 2.一条 SQL 查询语句在 MySQL 中如何执行的&#xff1f; 3.MySQL有哪些常见存储引擎&#xff1f; 4.那存储引擎应该怎么选择&#xff1f; 5.InnoDB和MylSAM主要有什么区别&#xff1f; 1.说说 MySQL 的基础架构? MySQL逻辑架构图主要分三…

浅谈古建筑电气火灾成因及防控对策

摘要: 我国古建筑多为砖木结构&#xff0c;当发生火灾事故时具有蔓延快、扑救难的特点&#xff0c;而火灾对古建筑的损害性很大&#xff0c;电气火灾事故在我国火灾事故中比重居高不下。本文通过对古建筑电气火灾成因进行分析&#xff0c;有针对性地提出了古建筑电气火灾防控对…