设计模式之备忘录模式笔记

设计模式之备忘录模式笔记

  • 说明
  • Memento(备忘录)
  • 目录
  • 白箱备忘录模式
    • 备忘录模式示例类图
    • 游戏角色类
    • 备忘录角色类
    • 备忘录对象管理对象
    • 测试类
  • 黑箱备忘录模式
    • 备忘录模式示例类图
    • 备忘录接口
    • 游戏角色类
    • 备忘录对象管理对象
    • 测试类

说明

记录下学习设计模式-备忘录模式的写法。JDK使用版本为1.8版本。

Memento(备忘录)

意图:在不破坏封装性的前提下捕获一个对象的内部状态,并在对象之外保存这个状态。这样以后就可以将对象恢复到原先保存的状态。
结构:
在这里插入图片描述

其中:

  • Memento(备忘录)存储原发器对象的内部状态,原发器根据需要决定备忘录存储原发器的哪些内部状态:防止原发器以外的其他对象访问备忘录。
  • Originator(原发器)创建一个备忘录,用于记录当前时刻它的内部状态;使用备忘录恢复内部状态。
  • Caretaker(管理者)负责保存好备忘录;不能对备忘录的内容进行操作或检查。

适用性:

  • 需要保存与恢复数据的场景,如玩游戏时的中间结果的存档功能。
  • 需要提供一个可回滚操作的场景,如 word记事本、Photoshop,idea等软件在编辑时按 Ctrl+ 组合键,还有数据库中事务操作。

目录

在这里插入图片描述

白箱备忘录模式

备忘录模式示例类图

在这里插入图片描述
在这里插入图片描述

以该UML类图实现白箱备忘录模式示例。

游戏角色类

package com.example.deesign_patterns.memento.white_box;//游戏角色类(属于发起人角色)
public class GameRole {private int vit;//生命力private int atk;//攻击力private int def;//防御力//初始化内部状态public void initState(){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 recoverState(RoleStateMemento roleStateMemento){//将备忘录对象中存储的状态赋值给当前对象的成员this.vit=roleStateMemento.getVit();this.atk=roleStateMemento.getAtk();this.def=roleStateMemento.getDef();}//展示状态功能public void stateDisplay(){System.out.println("角色生命力:"+vit);System.out.println("角色攻击力:"+atk);System.out.println("角色防御力:"+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.example.deesign_patterns.memento.white_box;//备忘录角色类
public class RoleStateMemento {private int vit;//生命力private int atk;//攻击力private int def;//防御力public RoleStateMemento() {}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.example.deesign_patterns.memento.white_box;//备忘录对象管理对象
public class RoleStateCaretaker {//声明RoleStateMemento类型的变量private RoleStateMemento roleStateMemento;public RoleStateMemento getRoleStateMemento() {return roleStateMemento;}public void setRoleStateMemento(RoleStateMemento roleStateMemento) {this.roleStateMemento = roleStateMemento;}
}

测试类

package com.example.deesign_patterns.memento.white_box;//测试类
public class Client {public static void main(String[] args) {System.out.println("-----------大战boos前-------------");//创建游戏角色对象GameRole gameRole=new GameRole();gameRole.initState();gameRole.stateDisplay();//将该游戏角色内部状态进行备份//创建管理者对象RoleStateCaretaker roleStateCaretaker=new RoleStateCaretaker();roleStateCaretaker.setRoleStateMemento(gameRole.saveState());System.out.println("-----------大战boos后-------------");//损耗严重gameRole.fight();gameRole.stateDisplay();System.out.println("-----------恢复之前的状态-------------");gameRole.recoverState(roleStateCaretaker.getRoleStateMemento());gameRole.stateDisplay();}
}

在这里插入图片描述

黑箱备忘录模式

备忘录模式示例类图

备忘录角色对发起人对象提供一个宽接口,而为其他对象提供一个窄接口。在Java语言中,实现双重接口的办法就是将备忘录类设计成发起人类的内部成员类。

将 RolestateMemento 设为 GameRole 的内部类,从而将 RoleStateMemento 对象封装在 Gamerole 里面:在外面提供-个标识接口 Memento 给 Rolestatecaretaker 及其对象使用。这样Gamerole 类看到的是 RoleStateMemento 所有的接口,而及其他对象看到的仅仅是标识接口 Memento 所暴露出来的接口,从而维护了封装型。类图如下:
在这里插入图片描述

以该UML类图实现黑箱备忘录模式示例。

备忘录接口

package com.example.deesign_patterns.memento.black_box;//备忘录接口,对外提供窄接口
public interface Memento {
}

游戏角色类

package com.example.deesign_patterns.memento.black_box;//游戏角色类(属于发起人角色)
public class GameRole {private int vit;//生命力private int atk;//攻击力private int def;//防御力//初始化内部状态public void initState(){this.vit=100;this.atk=100;this.def=100;}//战斗方法public void fight(){this.vit=0;this.atk=0;this.def=0;}//保存角色状态功能public Memento saveState(){return new RoleStateMemento(vit,atk,def);}//恢复角色状态public void recoverState(Memento memento){RoleStateMemento roleStateMemento= (RoleStateMemento) memento;//将备忘录对象中存储的状态赋值给当前对象的成员this.vit=roleStateMemento.getVit();this.atk=roleStateMemento.getAtk();this.def=roleStateMemento.getDef();}//展示状态功能public void stateDisplay(){System.out.println("角色生命力:"+vit);System.out.println("角色攻击力:"+atk);System.out.println("角色防御力:"+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;}//声明一个内部类private class RoleStateMemento implements Memento{private int vit;//生命力private int atk;//攻击力private int def;//防御力public RoleStateMemento() {}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.example.deesign_patterns.memento.black_box;//备忘录对象管理对象
public class RoleStateCaretaker {//声明Memento类型的变量private Memento memento;public Memento getMemento() {return memento;}public void setMemento(Memento memento) {this.memento = memento;}
}

测试类

package com.example.deesign_patterns.memento.black_box;//测试类
public class Client {public static void main(String[] args) {System.out.println("-----------大战boos前-------------");//创建游戏角色对象GameRole gameRole=new GameRole();gameRole.initState();gameRole.stateDisplay();//将该游戏角色内部状态进行备份//创建管理者对象RoleStateCaretaker roleStateCaretaker=new RoleStateCaretaker();roleStateCaretaker.setMemento(gameRole.saveState());System.out.println("-----------大战boos后-------------");//损耗严重gameRole.fight();gameRole.stateDisplay();System.out.println("-----------恢复之前的状态-------------");gameRole.recoverState(roleStateCaretaker.getMemento());gameRole.stateDisplay();}
}

在这里插入图片描述

好处:

  • 提供了一种可以恢复状态的机制。当用户需要时能够比较方便地将数据恢复到某个历史的状态。
  • 实现了内部状态的封装。除了创建它的发起人之外,其他对象都不能够访问这些状态信息。
  • 简化了发起人类。发起人不需要管理和保存其内部状态的各个备份,所有状态信息都保存在备忘录中,并由管理者进行管理,这符合单职责原则。

缺点:

  • 资源消耗大。如果要保存的内部状态信息过多或者特别频繁,将会占用比较大的内存资源。

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

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

相关文章

自制聊天机器人实现与chatgpt或微信好友对话【附代码】

闲来无事,想实现一个可与chatgpt或者微信好友对话的聊天机器人。该聊天机器人还可应用于QQ好友或者其他地方的语音输入。功能还是比较简单的,后期会慢慢更新,让人机交互体验感不断提升。 项目描述: 语音输入"开启语音助手&…

【kubernetes】负载均衡器安装部署-Haproxy与keepalived

前言:二进制部署kubernetes集群在企业应用中扮演着非常重要的角色。无论是集群升级,还是证书设置有效期都非常方便,也是从事云原生相关工作从入门到精通不得不迈过的坎。通过本系列文章,你将从虚拟机准备开始,到使用二进制方式从零到一搭建起安全稳定的高可用kubernetes集…

vite构建工具初识

一、什么是vite vite官网地址:https://cn.vitejs.dev/ Vite 是一个由 Vue.js 作者尤雨溪开发的新一代前端构建工具,它相比于传统的 webpack,具有更快的启动速度、更高的开发效率和更简洁的配置方式。 Vite的主要特点包括: 快速…

Java(七):项目部署

项目部署 运行容器解决Centos8中yum命令遇到的问题打包项目拷贝.jar到容器中安装jdk后台运行.jar后台运行.jar并输入日志实时查看日志查看/杀死运行程序目录结构日志配置 运行容器 $ docker run -d -p 8001:8001 -p 8081:8081 -p 8082:8082 --namelocal_centos --privilegedtr…

EasyCode代码生成插件-模板分享(基于数据表生成MyBatisPlus格式的dao,service,controller和vue组件)

目录 概述 使用演示 模板代码 实体类pojo 表现层controller 业务层service接口 业务层serviceImpl实现类 持久层dao Vue组件 概述 本片博客用于分享EasyCode的自定义模板(模板在篇末),用于简化开发,免去重复性的工作。 …

6.28作业

作业1 结构体不能被继承,类可以被继承结构体默认的都是公共,类默认是私有的 转载【结构体和类的区别】 结构体是值类型,类是引用类型 结构体存在栈中,类存在堆中 结构体成员不能使用protected访问修饰符,而类可以 结…

无法更新iPhone,提示“无法检查更新”怎么办?

当我们需要 iPhone更新系统时,可以前往iPhone设置-通用-软件更新中获取更新推送。不过一些用户可能会遇到无法更新的问题,例如会提示“无法检查更新,检查软件更新时出错”。 以上情况可能是网络问题,可以尝试重新打开设置&#xf…

vue中使用mock.js

安装mock npm install mockjs --save-dev或者在ui中选择依赖 查看安装是否成功 进入package.json文件 配置mock 在src目录下新建mock文件夹,在mock文件夹下建立index.js 配置模拟请求数据 index.js import Mock from mockjsconst loginData Mock.mock(http://l…

YOLOv5图像和视频对象生成边界框的目标检测实践(GPU版本PyTorch错误处理)

识别图像和视频里面的对象,在计算机视觉中是一个很重要的应用,比如无人驾驶,这个就需要实时的检测到周边环境的各种对象,并及时做出处理。目标检测在以往的文章中有重点讲解过几种,其中Faster R-CNN的源码解读&#xf…

Spring Bean的实例化过程

一、前言 对于写Java的程序员来说,Spring已经成为了目前最流行的第三方开源框架之一,在我们充分享受Spring IOC容器带来的红利的同时,我们也应该考虑一下Spring这个大工厂是如何将一个个的Bean生产出来的,本期我们就一起来讨论一…

局域网远程连接

一根网线连接两台电脑 前言步骤1 设置B“允许远程连接”2 A和B必须在同一个网段下面3 “winr”,输入“mstsc”中4 弹出“远程桌面连接”窗口,输入B的ip地址和B电脑的用户名及密码(winL键锁屏,看看B的用户名和密码是什么&#xff0…

注意力机制和Transformer

注意力机制和Transformer 机器翻译是NLP领域中最重要的问题之一,也是Google翻译等工具的基础。传统的RNN方法使用两个循环网络实现序列到序列的转换,其中一个网络(编码器)将输入序列转换为隐藏状态,而另一个网络&…