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


    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))
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 输出
    创建一条备忘录:&{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}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    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

    在这里插入图片描述

  • 相关阅读:
    vite打包vue2 history路由模式的的项目部署线上后<router-view />页面显示空白,命令行也不报错,本地是没有问题的
    H5 微信扫一扫
    2022年0630-Com.Java.Basis第一课《Java的入门程序》
    YYGH-BUG-04
    SAP-ABAP-RFC类型接口创建步骤
    【MediaSoup---源码篇】(三)Transport
    【学习笔记】CF1672G Cross Xor
    JS-(13) 事件(二)
    计算机组成原理_指令寻址
    【C++】开源:rapidjson数据解析库配置与使用
  • 原文地址:https://blog.csdn.net/xingzuo_1840/article/details/131896294