《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 mainimport "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 = statefmt.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.rhkb.cn/news/205296.html

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

相关文章

基于SpringBoot+Redis的前后端分离外卖项目-苍穹外卖(七)

分页查询、删除和修改菜品 1. 菜品分页查询1.1 需求分析和设计1.1.1 产品原型1.1.2 接口设计 1.2 代码开发1.2.1 设计DTO类1.2.2 设计VO类1.2.3 Controller层1.2.4 Service层接口1.2.5 Service层实现类1.2.6 Mapper层 1.3 功能测试1.3.2 前后端联调测试 2. 删除菜品2.1 需求分析…

可视化大屏时代的到来:智慧城市管理的新思路

随着科技的不断发展,智能芯片作为一种新型的电子元件,被广泛应用于各个领域,其中智慧芯片可视化大屏是一种重要的应用形式。 一、智慧芯片可视化大屏的优势 智慧芯片可视化大屏是一种将智能芯片与大屏幕显示技术相结合的产品,山海…

[pyqt5]pyqt5设置窗口背景图片后上面所有图片都会变成和背景图片一样

pyqt5的控件所有都是集成widget,窗体设置背景图片后控件背景也会跟着改变,此时有2个办法。第一个办法显然我们可以换成其他方式设置窗口背景图片,而不是使用styleSheet样式表,网上有很多其他方法。还有个办法就是仍然用styleSheet…

redis---主从复制及哨兵模式(高可用)

主从复制 主从复制:主从复制是redis实现高可用的基础,哨兵模式和集群都是在主从复制的基础之上实现高可用。 主从负责的工作原理 1、主节点(master) 从节点(slave)组成,数据复制是单向的&a…

IP-Adapter:文本兼容图像提示适配器,用于文本到图像扩散模型

IP-Adapter这是一种有效且轻量级的适配器,用于实现预训练文本到图像扩散模型的图像提示功能。只有 22M 参数的 IP 适配器可以实现与微调图像提示模型相当甚至更好的性能。IP-Adapter 不仅可以推广到从同一基本模型微调的其他自定义模型,还可以推广到使用…

Linux小程序之进度条

> 作者简介:დ旧言~,目前大二,现在学习Java,c,c,Python等 > 座右铭:松树千年终是朽,槿花一日自为荣。 > 目标:自己能实现进度条 > 毒鸡汤: > …

js双击修改元素内容并提交到后端封装实现

前面发过一个版本了,后来又追加了些功能。重新发一版。新版支持select和radio。 效果图: 右上角带有绿标的,是可以修改的单元格。如果不喜欢显示绿标,可以传递参数时指定不显示,如果想改为其它颜色,也可以…

[Java]JUC并发编程

JUC并发编程 一、什么是JUC 使用到 java.util 工具包、包、分类 二、线程和进程 进程:一个正在运行的程序,QQ.exe Music.exe 程序的集合; 一个进程往往可以包含多个线程,至少包含一个! Java默认有两个线程&#x…

浅学指针(3)

系列文章目录 文章目录 系列文章目录前言系列文章目录前言1. 字符指针变量2. 数组指针变量那数组指针变量应该是:存放的应该是数组的地址,能够指向数组的指针变量。2.2 数组指针变量怎么初始化总结:函数名就是地址,&函数名和直…

ubuntu22.04在线安装redis,可选择版本

安装脚本7.0.5版本 在线安装脚本,默认版本号是7.0.5,可以根据需要选择需要的版本进行下载编译安装 sudo apt-get install gcc -y sudo apt-get install pkg-config -y sudo apt-get install build-essential -y#安装redis rm -rf ./tmp.log systemctl …

AI4S Cup学习赛-中枢神经系统药物研发:药物筛选与优化

赛题介绍 链接:Bohrium 案例广场 (dp.tech) 中枢神经系统类疾病长期以来存在着重要的临床未满足需求。据统计,在当前人口老龄化趋势下,阿兹海默(AD)、帕金森病(PD)等神经退行性疾病和脑癌、中…

MySQL主从复制架构

MySQL主从复制架构 一、MySQL集群概述 ##1、集群的主要类型 高可用集群(High Available Cluster,HA Cluster) 高可用集群是指通过特殊的软件把独立的服务器连接起来,组成一个能够提供故障切换(Fail Over&#xff09…

【前端系列】前端存档术之keep-alive

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

电子学会C/C++编程等级考试2022年09月(三级)真题解析

C/C++等级考试(1~8级)全部真题・点这里 第1题:课程冲突 小 A 修了 n 门课程, 第 i 门课程是从第 ai 天一直上到第 bi 天。 定义两门课程的冲突程度为 : 有几天是这两门课程都要上的。 例如 a1=1,b1=3,a2=2,b2=4 时, 这两门课的冲突程度为 2。 现在你需要求的是这 n 门课…

如何设置Linux终端提示信息

如何设置Linux终端提示信息 1 方法一:只能在VSCode或者Pycharm终端显示提示信息2 方法二:只能在MobaXterm等远程软件上显示提示3 方法三:避免用户没看到上面的提示,上面两种都设置一下 在使用远程终端时,由于多用户使用…

Qt 软件调试(一) Log日志调试

终于这段时间闲下来了,可以系统的编写Qt软件调试的整个系列。前面零零星星的也有部分输出,但终究没有形成体系。借此机会,做一下系统的总结。慎独、精进~ 日志是有效帮助我们快速定位,找到程序异常点的实用方法。但是好的日志才能…

MATLAB | 官方举办的动图绘制大赛 | 第三周赛情回顾

MATHWORKS官方举办的迷你黑客大赛第三期(MATLAB Flipbook Mini Hack)的最新进展!! 很荣幸前三周都成为了阶段性获奖者~: https://ww2.mathworks.cn/matlabcentral/communitycontests/contests/6/entries/13382 https://ww2.mathworks.cn/mat…

实验一 SAS 基本操作和数据表的导入 2023-11-29

一、上机目的 熟悉SAS的集成环境并掌握它的基本操作。理解SAS程序的结构,理解其中的过程,过程选项,语句,语句选项等概念,掌握SAS编程技术。 二、上机内容 主要有SAS操作界面、SAS窗口操作、SAS菜单操作、SAS按钮操作…

【Java】泛型的简单使用

文章目录 一、包装类1.基本数据类型和对应的包装类2.自动装箱和自动拆箱3.手动装箱和手动拆箱 二、什么是泛型三、泛型的使用四、裸类型(Raw Type)五、泛型是如何编译的六、泛型的上界七、泛型方法总结 一、包装类 在了解泛型之前我们先了解什么是包装类…

对称加密与非对称加密的区别是什么?

对称加密与非对称加密的区别是什么? 对称加密概念:好处和坏处:基本原理 非对称加密概念:工作原理: 两者区别安全性处理速度密钥管理通信双方数量 对称加密 概念: 同一个密钥可以同时用来对信息进行加密和…