设计模式之备忘录模式(上)

备忘录模式
1)概述
1.定义

在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,可以在以后将对象恢复到原先保存的状态。

2.作用

备忘录模式提供了一种状态恢复的实现机制,使得用户可以方便地回到一个特定的历史步骤,当新的状态无效或者存在问题时,可以使用暂时存储起来的备忘录将状态复原。

3.结构图

在这里插入图片描述

4.角色

Originator(原发器):它是一个普通类,可以创建一个备忘录,并存储它的当前内部状态,也可以使用备忘录来恢复其内部状态,一般将需要保存内部状态的类设计为原发器。

Memento(备忘录):存储原发器的内部状态,根据原发器来决定保存哪些内部状态。

Caretaker(负责人):负责人又称为管理者,它负责保存备忘录,但是不能对备忘录的内容进行操作或检查,在管理者类中可以存储一个或多个备忘录对象,它只负责存储对象,而不能修改对象,也无须知道对象的实现细节。

5.代码实现

原发器类Originator

public class Originator {
    private String state;
    public Originator(){}
    
  // 创建一个备忘录对象
    public Memento createMemento() {
    return new Memento(this);
    }
 
  // 根据备忘录对象恢复原发器状态
    public void restoreMemento(Memento m) {
     state = m.state;
    }
 
    public void setState(String state) {
        this.state=state;
    }
 
    public String getState() {
        return this.state;
    }
}

备忘录类Memento

//备忘录类,默认可见性,包内可见
class Memento {
    private String state;
 
    public Memento(Originator o) {
    state = o.getState();
    }
 
    public void setState(String state) {
        this.state=state;
    }
 
    public String getState() {
        return this.state;
    }
}
6.Java语言实现备忘录模式

一般将Memento类与Originator类定义在同一个包(package)中实现封装,在Java语言中可使用默认访问标识符来定义Memento类,保证只有Originator类可以对Memento进行访问。

在Memento中保存了Originator的state值,如果Originator中的state值改变之后需撤销,可以通过调用它的restoreMemento()方法进行恢复。

对于负责人类Caretaker,它用于保存备忘录对象,并提供getMemento()方法向客户端返回一个备忘录对象,原发器通过使用这个备忘录对象可以回到某个历史状态,典型的负责人类的实现代码如下:

public class Caretaker {
	private Memento memento;
 
	public Memento getMemento() {
		return memento;
	}
 
	public void setMemento(Memento memento) {
		this.memento=memento;
	}
}

在Caretaker类中不应该直接调用Memento中的状态改变方法,它的作用仅仅用于存储备忘录对象。

7.注意

设计备忘录类时需要考虑其封装性,除了Originator类,不允许其他类来调用备忘录类Memento的构造函数与相关方法,如果不考虑封装性,允许其他类调用setState()等方法,将导致在备忘录中保存的历史状态发生改变,通过撤销操作所恢复的状态就不再是真实的历史状态,备忘录模式也就失去了本身的意义。

2)完整解决方案
1.结构图

在这里插入图片描述

Chessman充当原发器,ChessmanMemento充当备忘录,MementoCaretaker充当负责人,在MementoCaretaker中定义了一个ChessmanMemento类型的对象,用于存储备忘录。

2.代码实现
//象棋棋子类:原发器
@Data
public class Chessman {
	private String label;
	private int x;
	private int y;
 
	public Chessman(String label,int x,int y) {
		this.label = label;
		this.x = x;
		this.y = y;
	}
	
  //保存状态
	public ChessmanMemento save() {
		return new ChessmanMemento(this.label,this.x,this.y);
	}
	
  //恢复状态
	public void restore(ChessmanMemento memento) {
		this.label = memento.getLabel();
		this.x = memento.getX();
		this.y = memento.getY();
	}
}
 
//象棋棋子备忘录类:备忘录
@Data
class ChessmanMemento {
	private String label;
	private int x;
	private int y;
 
	public ChessmanMemento(String label,int x,int y) {
		this.label = label;
		this.x = x;
		this.y = y;
	}	
}
 
//象棋棋子备忘录管理类:负责人
public class MementoCaretaker {
	private ChessmanMemento memento;
 
	public ChessmanMemento getMemento() {
		return memento;
	}
 
	public void setMemento(ChessmanMemento memento) {
		this.memento = memento;
	}
}

客户端类

public class Client {
	public static void main(String[] args) {
		MementoCaretaker mc = new MementoCaretaker();
		
		Chessman chess = new Chessman("车",1,1);
		display(chess);
		mc.setMemento(chess.save()); //保存状态		
		
		chess.setY(4);
		display(chess);
		mc.setMemento(chess.save()); //保存状态
		display(chess);
		
		chess.setX(5);
		display(chess);
		
		System.out.println("******悔棋******");	
		//恢复状态
		chess.restore(mc.getMemento()); 
		display(chess);
	}
	
	public static void display(Chessman chess) {
		System.out.println("棋子" + chess.getLabel() + "当前位置为:" + "第" + chess.getX() + "行" + "第" + chess.getY() + "列。");
	}
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

展厅设计方案需要考虑哪些因素环节

1、整体展厅规划 整体规划是展厅搭建中需要优先考虑的环节,必须为搭建成本和效果提供坚实的基础。需确定整体展厅面积、展厅的使用目的、产品布局以及进入展厅的路线、确定展厅的整体框架之后,还需考虑展品种类、产生的呈现效果,这些都将影响…

el-table动态合并列

需要合并列,并且不确定需要合并多少列的,可以参照如下代码 首先需要再el-table上传入span-method方法 arraySpan({ row, column, rowIndex, columnIndex }){if (row.groupName 汇总 && columnIndex 0) {return [0,0]} else if (row.groupName…

迷宫 — — 蓝桥杯(动态规划)

迷宫 题目: 输入样例: 3 1 1 1 2 3 4 5 6 7 8 9 2 2 1 3 1 R输出样例: 21思路: 题目大意:给定一个n x m的平面网格,并且每一个格子都有一定的代价,并且设有障碍物和陷阱,障碍物的意…

win11 连接海康摄像头 ONVif协议

目录 Win 11 通过脚本打开自带的IE浏览器访问海康摄像头 海康摄像头设置支持onvif协议 安装onvif协议 onvif协议示例代码 Win 11 通过脚本打开自带的IE浏览器访问海康摄像头 第一步、桌面右键新建一个 txt 的文档 第二步、打开文档并且复制粘贴下面代码 CreateObject(&…

【科研】搜索文献的网站

文章目录 paperswithcode【最新论文,代码】huggingface【大语言模型,最新论文】dblp【关键词搜索】arxiv【最新文章】semanticscholar【相关引用查询】connectedpapers【相关引用查询】github【工程,代码,论文开源代码】 paperswi…

OV证书为什么更可信

在网络安全领域,SSL/TLS证书扮演着至关重要的角色,其中组织验证(Organization Validation,简称OV)证书以其深度验证机制和高度可信性脱颖而出。 OV证书为何更值得信赖,关键在于其严格的验证流程。 首先&am…

金三银四面试题(十九):MySQL中的锁

在MySQL中,锁是非常重要的,特别是在多用户并发访问数据库的环境中,因此也是面试中常问的话题。 请说说数据库的锁? 关于MySQL 的锁机制,可能会问很多问题,不过这也得看面试官在这方面的知识储备。 MySQL …

东方博宜 1169. 编程输入10个正整数,然后自动按从大到小的顺序输出

东方博宜 1169. 编程输入10个正整数&#xff0c;然后自动按从大到小的顺序输出 学了sort函数的新用法。 从小到大排列 sort(a , an ) 从大到小排列 sort(a , an , greater() ) #include<iostream> #include<algorithm> using namespace std; int main() {int a[…

瑞_23种设计模式_访问者模式

文章目录 1 访问者模式&#xff08;Visitor Pattern&#xff09;1.1 介绍1.2 概述1.3 访问者模式的结构1.4 访问者模式的优缺点1.5 访问者模式的使用场景 2 案例一2.1 需求2.2 代码实现 3 案例二3.1 需求3.2 代码实现 4 拓展——双分派4.1 分派4.2 动态分派&#xff08;多态&am…

新型[datahelper@onionmail.org].datah 勒索病毒来袭:如何筑起安全防线?

在数字化时代&#xff0c;网络安全问题日益凸显&#xff0c;其中勒索病毒成为了一种非常严重的威胁。[datahelperonionmail.org].datah勒索病毒就是其中的佼佼者&#xff0c;它以其复杂的加密手段和恶劣的勒索行为&#xff0c;给用户带来了巨大的损失。本文将从病毒的运行机制、…

systemctl start docker报错(code=exited, status=1/FAILURE)

运行systemctl start docker报错内容如下: 输入systemctl status docker.service显示以下内容&#xff1a; 本次启动不起来与docker服务无关 具体解决问题是修改 /etc/docker/daemon.json&#xff0c;vim /etc/docker/daemon.json # 添加如下内容 {"registry-mirrors&qu…

Win10安装sqlplus遇到报错的解决办法

1.下载安装sqlplus.exe的错误解决过程 最近有用到sqlplus连接Oracle数据库执行自动化脚本&#xff0c;Orcle服务器版本是11.2.0.1。在Navicat工具上通过如下语句查询到的版本信息截图如图1所示&#xff1a; SELECT * FROM v$version; 图1 Oracle服务器版本信息 其中“Oracle Da…

图像分割-RSPrompter

文章目录 前言1. 自动化提示器1.1 多尺度特征增强器1.2 RSPrompterAnchor-based PrompterQuery-based Prompter 2. SAM的扩展3. 结果WHU数据集NWPU数据集SSDD数据集 前言 《RSPrompter: Learning to prompt for remote sensing instance segmentation based on visual foundati…

面试算法-172-对称二叉树

题目 给你一个二叉树的根节点 root &#xff0c; 检查它是否轴对称。 示例 1&#xff1a; 输入&#xff1a;root [1,2,2,3,4,4,3] 输出&#xff1a;true 解 class Solution {public boolean isSymmetric(TreeNode root) {return isSymm(root.left,root.right);}public b…

Python学习笔记——heapq

堆排序 思路 堆排序思路是&#xff1a; 将数组以二叉树的形式分析&#xff0c;令根节点索引值为0&#xff0c;索引值为index的节点&#xff0c;子节点索引值分别为index*21、index*22&#xff1b;对二叉树进行维护&#xff0c;使得每个非叶子节点的值&#xff0c;都大于或者…

Redis持久化策略详解

文章目录 前言一、RDB(Redis Database)1.1 概念1.2 触发方式 二、AOF(Append Only File)2.1 概念2.2 AOF持久化策略2.3 AOF文件重写2.4 触发条件2.5 AOF配置说明 三、混合持久化3.1 概念3.2 开启混合持久化3.3 加载流程3.4 混合持久化优劣势 四、总结4.1 RDB和AOF各自有什么优缺…

一文带你了解Material, Texture Mapping, Shading, Shader

作者&#xff1a;caven chen 在计算机图形学和三维开发过程中&#xff0c;有几个容易混淆的概念。今天我们来一举拿下。 又可以学习新的知识啦。冲鸭。。。。。。 基础概念 首先我们来介绍一些基础概念: 英文 中文 本质 释义 Material 材质 数据集 表现物体对光的交互…

VirusTaxo:病毒物种注释

https://github.com/omics-lab/VirusTaxo 安装 git clone https://github.com/omics-lab/VirusTaxo mamba create -n VirusTaxo python3.10 mamba activate VirusTaxo cd VirusTaxo python3 -m venv environment source ./environment/bin/activate pip install -r require…

【JavaWeb】Day40.MySQL概述——多表设计(一对多)

多表设计 项目开发中&#xff0c;在进行数据库表结构设计时&#xff0c;会根据业务需求及业务模块之间的关系&#xff0c;分析并设计表结构&#xff0c;由于业务之间相互关联&#xff0c;所以各个表结构之间也存在着各种联系&#xff0c;基本上分为三种&#xff1a; 一对多(多…

【机器学习算法】决策树和随机森林在计算机视觉中的应用

前言 决策树和随机森林在计算机视觉中有着广泛的应用。决策树作为一种简单而强大的分类模型&#xff0c;可以用于图像分类、目标检测、特征提取等任务。它能够根据图像的特征逐层进行判断和分类&#xff0c;从而实现对图像数据的智能分析和理解。随机森林作为一种集成学习方法&…