《golang设计模式》第三部分·行为型模式-06-备忘录模式(Memento)

文章目录

  • 1. 概述
    • 1.1 角色
    • 1.2 类图
  • 2. 代码示例
    • 2.1 设计
    • 2.2 代码
    • 2.3 类图

1. 概述

备忘录(Memento)用于在不破坏目标对象封装特性的基础上,将目标对象内部的状态存储到外部对象中,以备之后恢复状态时使用。

1.1 角色

  • Originator(发起者):当前的基础对象,它会将自己的状态保存进备忘录。
    • savememento()方法:Originator通过该方法将它自己状态保存进一个备忘录对象。
    • restorememento()方法:Originator通过该方法将它自己状态回滚至指定备忘录。
  • Memento(备忘录) : 存储Originator状态的对象
  • Caretaker(管理者):保存多条备忘录的对象,并维护着备忘录的索引,在需要的时候会返回相应的备忘录。

1.2 类图

Originator
-state:State
+RestoreState(m:Memento)
+CreateMemento()
Memento
-state:State
+GetState()
Caretaker
+StoreMemento(m:Memento)
+GetMemento(c:Condition)

2. 代码示例

2.1 设计

  • 定义备忘录memento来记录发起者状态
  • 它的Get()方法获取它的状态
  • 定义发起者Originator
    • 它的方法 CreateMemento() 用它自己创建一条备忘录
    • 它的方法 RollBack() 将它自己回滚至指定备忘录的状态
    • 它的Set()方法可以设置它的状态
    • 它的Get()方法可以获取它的状态
  • 创建一个管理者Caretaker,它是备忘录Memento的聚合
    • 它的AddMemento方法,向它自身加入一条备忘录
    • 它的GetMemento()方法,查询一条它管理的指定备忘录
  • 调用
    • 初始化
      • 实例化一个管理者caretaker
      • 实例化一个发起者originator
    • 创建备忘录测试
      • 第一次
        • 用发起者创建一条备忘录
        • 管理者收录该备忘录
      • 第二次
        • 改变发起者状态
        • 用发起者创建一条新备忘录
        • 管理者收录该备忘录
      • 第三次
        • 改变发起者状态
        • 用发起者创建一条新备忘录
        • 管理者收录该备忘录
      • 查看管理者信息,应该有三条备忘录
    • 回滚测试
      • 从管理者获取指定索引的备忘录
      • 将发起者回滚至该备忘录状态

2.2 代码

  • 代码
package main

import "fmt"

// 定义备忘录
type Memento struct {
	state string
}

// 查备忘录状态
func (m *Memento) Get() string {
	return m.state
}

// 定义发起者
type Originator struct {
	state string
}

// 根据发起者状态创建一条备忘录
func (e *Originator) CreateMemento() (memento *Memento) {
	memento = &Memento{state: e.state}
	fmt.Printf("创建一条备忘录:%+v\n", memento)
	return memento
}

// 将发起者状态回滚至指定备忘录状态
func (e *Originator) RollBack(m *Memento) {
	e.state = m.Get()
	fmt.Printf("发起者状态回滚至:%v\n", e)
}

// 设置发起者状态
func (e *Originator) Set(state string) {
	e.state = state
	fmt.Println("发起者状态更改为:", e.state)
}

// 获取发起者状态
func (e *Originator) Get() string {
	fmt.Println("获取发起者状态为:", e.state)
	return e.state
}

// 定义管理者,管理者是备忘录的聚合
type Caretaker struct {
	mementoArray []*Memento
}

// 向管理者中添加一条备忘录
func (c *Caretaker) AddMemento(m *Memento) {
	fmt.Printf("向管理者中添加一条备忘录:%+v\n", m)
	c.mementoArray = append(c.mementoArray, m)
}

// 获取指定备忘录信息
func (c *Caretaker) GetMemento(index int) *Memento {
	fmt.Printf("获取到第 %d 条备忘录信息为:%+v\n", index, c.mementoArray[index])
	return c.mementoArray[index]
}

func main() {
	//实例化一个管理者
	caretaker := &Caretaker{
		mementoArray: make([]*Memento, 0),
	}
	//实例化一个发起者
	originator := &Originator{
		state: "A",
	}

	//为发起者创建一条备忘录
	memento0 := originator.CreateMemento()
	//在管理者中加入该备忘录
	caretaker.AddMemento(memento0)

	//改变发起者状态
	originator.Set("B")
	//为发起者创建第二条备忘录
	memento1 := originator.CreateMemento()
	//在管理者中加入该备忘录
	caretaker.AddMemento(memento1)

	//再次改变发起者状态
	originator.Set("C")
	//为发起者创建第三条备忘录
	memento2 := originator.CreateMemento()
	//在管理者中加入该备忘录
	caretaker.AddMemento(memento2)
	fmt.Println("此时管理者应该有三条备忘录:")
	for _, memento := range caretaker.mementoArray {
		fmt.Printf("%+v\n", memento)
	}
	
	fmt.Println("=========回滚测试===========")
	originator.RollBack(caretaker.GetMemento(1))
	fmt.Println("=========回滚测试===========")
	originator.RollBack(caretaker.GetMemento(0))
}
  • 输出
创建一条备忘录:&{state:A}
向管理者中添加一条备忘录:&{state:A} 
发起者状态更改为: B
创建一条备忘录:&{state:B}
向管理者中添加一条备忘录:&{state:B} 
发起者状态更改为: C
创建一条备忘录:&{state:C}
向管理者中添加一条备忘录:&{state:C} 
此时管理者应该有三条备忘录
&{state:A}
&{state:B}
&{state:C}
=========回滚测试===========
获取到第 1 条备忘录信息为:&{state:B}
发起者状态回滚至:&{B}
=========回滚测试===========
获取到第 0 条备忘录信息为:&{state:A}
发起者状态回滚至:&{A}

2.3 类图

Originator
-string:State
+CreateMemento()
+RollBack(m *Memento)
+Set(state string)
+Get()
Memento
-String:State
+Get()
Caretaker
+[]*Memento:mementoArray
+AddMemento(m *Memento)
+GetMemento(index int) : Memento

在这里插入图片描述

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

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

相关文章

ABAP调用Https接口 Ssl证书导入

ABAP调用Https接口 Ssl证书导入 一、证书导入 谷歌浏览器打开对方系统URL地址,下载SSL Server certificate,步骤如下: 浏览器打开要导出certificate(证书)的网站,点击这个小锁的图标: 点击连接是安全的后面小播放按钮 点击证…

【教3妹学编程-算法题】最大异或乘积

3妹:2哥,你有没有看到新闻“18岁父亲为4岁儿子落户现身亲子鉴定” 2哥 : 啥?18岁就当爹啦? 3妹:确切的说是14岁好吧。 2哥 : 哎,想我30了, 还是个单身狗。 3妹:别急啊, 2…

化繁为简——2021版本Adobe InDesign

今天,我们来谈谈Id软件,它是一个定位于专业排版领域的设计软件,虽然出道时间比较晚,但是在功能上反而更加完美与成熟。InDesign可以将文档直接导出为Adobe的PDF格式,而且有多语言支持。它也是第一个支持Unicode文本处理…

TVS瞬态抑制二极管的工作原理和特点?|深圳比创达电子EMC

TVS二极管一般是用来防止端口瞬间的电压冲击造成后级电路的损坏。防止端口瞬间的电压冲击造成后级电路的损坏。有单向与双向之分,单向TVS一般应用于直流供电电路,双向TVS应用于交流供电电路。 TVS产品的额定瞬态功率应大于电路中可能出现的最大瞬态浪涌…

SpringCloud 微服务全栈体系(十六)

第十一章 分布式搜索引擎 elasticsearch 六、DSL 查询文档 elasticsearch 的查询依然是基于 JSON 风格的 DSL 来实现的。 1. DSL 查询分类 Elasticsearch 提供了基于 JSON 的 DSL(Domain Specific Language)来定义查询。常见的查询类型包括&#xff1…

初学者必读书籍——两个月速成Python

想学Python的你是不是一直被它生涩难懂的劝退?作为一个自学入门的程序员,依靠这样几本书,两个月就学会了python。不卖关子,我学的就是”python编程三剑客“系列。那么接下来就让我给你介绍介绍吧。 1.《Python编程:从入…

解析生成式人工智能 | 它真的有这么强大吗?

原创 | 文 BFT机器人 当人们说“生成式人工智能”时,你知道这代表着什么意思吗?为什么这些系统似乎正在覆盖所有涉及联想的应用程序?近日,麻省理工学院的人工智能专家帮助剖析了这种日益流行且无处不在的技术。 当你快速浏览一下头…

如何看待程序员领域内的“内卷”现象?

要搞清楚这个问题,我首先就来阐释一下“内卷”的概念。 内卷本身是从一个学术名词演化为网络流行词的,本是指文化模式因达到某种最终形态,既无法保持稳定也不能转化为更高级的新形态,而只能在这种文化模式内部无限变得复杂的现象。…

HTML+CSS+ElementUI搭建个人博客静态页面展示(纯前端)

网站演示 搭建过程 技术选取 HTML/CSSVUE2ElementUI(Version - 2.15.14) 环境配置与搭建 安装指令 1. 先确保你的电脑已经安装好了npm和node npm -vnode -v2. ElementUI下载&#xff0c;推荐使用 npm 的方式安装 npm i element-ui -S3. CDN引入 <!-- 引入样式 --> <…

Redis 与其他数据库的不同之处 | Navicat

Redis&#xff0c;即远程字典服务器&#xff08;Remote Dictionary Server&#xff09;&#xff0c;它是一个多功能且高性能的键值存储系统&#xff0c;在数据库领域中已获得广泛关注和认可。在处理简单数据结构方面&#xff0c;它因其快速和高效而著称。本文中&#xff0c;我们…

基于高质量训练数据,GPT-4 Turbo更出色更强大

11月7日消息&#xff0c;OpenAI在首届开发者大会上正式推出了GPT-4 Turbo。 与GPT-4相比&#xff0c;GPT-4 Turbo主要有6方面的提升&#xff1a; 1、扩展下文对话长度&#xff1a;GPT4最大只能支持8k的上下文长度&#xff08;约等于6000个单词&#xff09;&#xff0c;而GPT-4…

SOLIDWORKS实用技巧——工程图模板替换

概述 工程师常在出图时选择最佳模板&#xff0c;在编辑一段时间后&#xff0c;发现需要更改图纸大小&#xff0c;怎样更改图纸大小还不影响现有工作。你是否也有此类问题&#xff1f; 那么&#xff0c;新建工程图时的模板从哪里来&#xff1f;如何轻松替换已有工程图的图纸格…

你还记得你常用的数据库有哪些吗?

接上文&#xff0c;常用数据库有哪些 Oracle 开发厂商&#xff1a;甲骨文公司 最新版本&#xff1a;Oracle Database 19c&#xff08;长期支持版&#xff09;、Oracle Database 21c&#xff08;创新版&#xff0c;已生产可用&#xff09; 发行方式: 商业软件&#xff08;Comme…

swagger的ApiImplicitParam注解中的required属性不起作用

问题的发现 如上两图&#xff0c;在接口中使用了’ApiImplicitParam’注解&#xff0c;仅指定了一个参数是必填&#xff0c;但是通过swagger文档查看三个参数均不能为空。 原因探究 最终确定到因为在RequestParam中也有一个required属性&#xff0c;用于指定是否必填。swagge…

ERP对接淘宝/天猫/京东/拼多多商品详情数据API接口

引言 今天&#xff0c;我们时代变化非常快&#xff0c;传统行业做法&#xff0c;已经无法完全适应时代的发展。互联网的发展&#xff0c;造成了一股网购热。京东&#xff0c;天猫&#xff0c;淘宝&#xff0c;易购……网购&#xff0c;给我们生活带来了方便&#xff0c;消费者…

系统试运行方案

系统试运行的目的&#xff1a; 试运行目的通过既定时间段的试运行&#xff0c;全面考察项目建设成果。并通过试运行发现项目存在的问题&#xff0c;从而进一步完善项目建设内容&#xff0c;确保项目顺利通过竣工验收并平稳地移交给运行管理单位。通过实际运行中系统功能与性能的…

股票基础数据(二)

二. 股票基础数据 文章目录 二. 股票基础数据一. 查询股票融资信息数据二. 查询所有的股票信息三. 查询所有的股票类型信息四. 根据类型查询所有的股票数据信息五. 查询股票当前的基本信息六. 查询股票的K线图, 返回对应的 base64 信息七. 展示股票的K线图数据, 对应的是数据信…

Go 异常处理流程

在 Go 语言中&#xff0c;panic、recover 和 defer 是用于处理异常情况的关键字。它们通常一起使用来实现对程序错误的处理和恢复。 1. defer 语句 defer 用于在函数返回之前执行一段代码。被 defer 修饰的语句或函数会在包含 defer 的函数执行完毕后执行。defer 常用于资源清…

服务器 jupyter 文件名乱码问题

对于本台电脑&#xff0c;autodl服务器&#xff0c;上传中文文件时&#xff0c;从压缩包名到压缩包里的文件名先后会出现中文乱码的问题。 Xftp 首先是通过Xftp传输压缩包到Autodl服务器&#xff1a; 1、打开Xftp&#xff0c;进入软件主界面&#xff0c;点击右上角【文件】菜…

Nacos升级2.2.2 相关版本升级及升级中问题【下篇】

上篇对nacos进行了升级&#xff0c;如果有不清楚的小伙伴可以参考文章&#xff1a;https://blog.csdn.net/weixin_38801572/article/details/130237813 本篇主要是对升级后的鉴权问题进行处理&#xff0c;找了好多的文章都是添加username、password操作&#xff0c;但是实际操作…