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

news2024/12/24 14:17:31

文章目录

  • 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

在这里插入图片描述

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

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

相关文章

kibana 7安装

手动安装 下载 wget https://artifacts.elastic.co/downloads/kibana/kibana-7.17.15-linux-x86_64.tar.gz 解压 mv kibana-7.17.15-linux-x86_64.tar.gz /usr/local tar -zxvf kibana-7.17.15-linux-x86_64.tar.gz chown -R es:es kibana-7.17.15-linux-x86_64修改配置 s…

深圳锐科达SV-X7 sip话机与海康威视摄像头联动设置方法

深圳锐科达SV-X7 sip话机与海康威视摄像头联动设置方法 SIP对讲终端获取设备IP地址方式 通过长按速拨键3秒(上电30秒后,即听到提示音后),待喇叭发出急促嘟嘟声,再快速按一下速拨键,设备自动语音播报本机的…

Vue弹窗的使用

Vue弹窗的使用: Vue弹窗传值:

requests 库中响应最大文件大小和最大连接超时时间的设定

最近,requests-toolbelt库的开发者jvanasco提出了一项特性请求,即在发送请求时设置响应的最大文件大小和最大连接超时时间。 对于最大连接超时时间的问题,我们可以借鉴requests-toolbelt库的开发者kevinburke的建议,将请求放入线程…

基于SSM的焦作旅游协会管理系统设计与实现

末尾获取源码 开发语言:Java Java开发工具:JDK1.8 后端框架:SSM 前端:采用JSP技术开发 数据库:MySQL5.7和Navicat管理工具结合 服务器:Tomcat8.5 开发软件:IDEA / Eclipse 是否Maven项目&#x…

3D打印新突破:可一次性打印出带骨骼、肌腱、韧带的机械手

原创 | 文 BFT机器人 近日,来自瑞士苏黎世联邦理工学院 (ETH) 和美国初创公司Inkbit的研究团队采用最新的激光扫描技术,成功地实现了机械手的3D打印,其内部结构由类人骨骼、韧带和肌腱组成。这项新技术使一次性3D打印具有弹性的特种塑料成为…

足底筋膜炎症状及治疗方法

足底筋膜炎是一种常见的足部疾病,通常会引起足跟疼痛和不适。这种疼痛通常在早晨起床后或者长时间休息后更为明显,行走一段时间后可能会减轻。下面我们将详细介绍足底筋膜炎的症状及治疗方法。 一、足底筋膜炎的症状 足跟疼痛:这是足底筋膜…

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

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

HT513 I2S输入的音频功放的应用场景

HT513 I2S输入的音频功放的应用场景于:・智N家居 ・智N玩具 ・IoT设备 ・游戏设备・智N音箱 ・其他锂电/5V设备等等。 HT513内部集成了DA转换器,其I2S输入支持32-bit字节,并且可自动监测采样频率,支持192kHz。 HT513集成的D类音…

Spring——感谢尚硅谷官方文档

Spring——尚硅谷学习笔记 1 Spring简介👾1.1 Spring概述1.2 Spring Framework1.2.1 Spring Framework特性1.2.2 Spring Framework五大功能模块 2 IOC-IOC容器思想👾IOC容器思想IOC在Spring中的实现 3 IOC-基于XML文件管理Bean👾3.1 准备工作…

Cannot read properties of undefined (reading ‘resetFields‘)“ 报错解决

遇到这种报错 先去相关页面搜索关键字 定位到具体的报错代码 Cannot read properties of undefined (reading ‘resetFields’)" 关键字:resetFields 此方法作用:对整个表单进行重置 将所有字段值重置为初始值并移除校验结果 报错场景:…

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

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

Go 异常处理流程

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

Django学习日志09

choices参数的使用 """对于以上可能被我们列举完的字段我们一般都是选择使用choices参来做""" class UserInfo(models.Model):username models.CharField(max_length64)password models.CharField(max_length32)# 先写一个映射关系gender_cho…

电机应用开发-直流有刷电机速度环控制实现

直流有刷电机速度环控制实现 硬件设计 可选:L298N电机驱动板、野火MOS搭建的驱动板。 直流电机速度环控制-位置式PID实现 编程要点 配置定时器可以输出PWM控制电机 配置定时器可以读取编码器的计数值 配置基本定时器可以产生定时中断来执行PID运算 编写位置式PID算…

如何选择一款快速可靠的文件自动同步软件?

在企业的数据流转管控过程中,经常会遇到频繁的数据备份、同步,人工重复这样的工作程序,既繁琐又容易出错。越来越多的企业,要求内部各种业务数据在多台服务器之间、多个数据中心之间,乃至多云和本地之间调度和同步。很…

黔院长 | 中医上所说的虚实到底是什么?

虚实是中医上经常出现的词语,例如脾虚、肾虚等也都是我们经常听到的症状。各种病症的发生都有虚实的不同,那什么是虚实呢?在《黄帝内经》当中就有相关的叙述: 所谓虚实,是正气与邪气相比较而言的。什么是正什么是邪&am…

python 实现银行卡号查询银行名称和简称

本章教程利用python实现查询银行卡号名称和简称 。 目录 一、 实例代码 二、运行效果 一、 实例代码 #!/usr/bin/python # -*- coding: UTF-8 -*- """ author: Roc-xb desc: python 实现银行卡号查询银行简称 """ import requestsdef bank_mes…

Java入门篇 之 内部类

本篇碎碎念:本篇没有碎碎念,想分享一段话: 你不笨,你只是需要时间,耐心就是智慧,不见得快就好,如果方向都不对,如果心术不正,如果德不配位,快就是对自己天分的…

如何配置ESB单据集成接口

ESB企业服务总线在实际项目中主要用于各业务系统之间的集成,集成包括数据集成、应用集成以及业务单据集成等,ESB企业服务总线主要包含三部分:ESB设计器、SMC管理控制台以及Server运行环境,ESB设计器用于服务以及集成流程的开发&am…