【Go-设计模式】备忘录模式 详解

shadowLogo

概念:

备忘录模式(Memento Pattern)不破坏封装性不暴露内部情形 的前提下,捕获一个对象的 内部状态,并在 该对象之外 保存这个状态。
这样以后就可将该对象恢复到 原先保存的状态

程序 内部状态 使用 窄接口 传给 外部 进行 存储,从而 不暴露程序实现细节

备忘录模式 同时可以 离线保存内部状态,如保存到数据库,文件等

可以这样理解 备忘录模式
现实生活中的 备忘录 是用来记录 某些要去做的事情
或者是记录 已经达成的共同意见的事情,以防忘记了

而在 软件层面,备忘录模式有着 相同的含义,备忘录对象 主要用来 记录一个对象的某种状态,或者 某些数据
当要做 回退 时,可以从 备忘录对象 里获取 原来的数据 进行恢复操作

备忘录模式 属于 行为型模式

regard


UML:

uml

  • originator
    需要保存状态 的对象
  • Memento
    备忘录对象,负责 保存目标对象集合,即:Originator 内部状态
  • Caretaker
    负责人对象,负责 保存多个备忘录对象,也可以是 多个 originator 对象不同时间的状态,使用 集合 管理,提高效率

示例:

角色信息类:

type Originator struct {
	Attri1 string
	Attri2 int64
}

func (this *Originator) DoAction(detal1 string, detal2 int64) {
	fmt.Println("【角色升级,获得属性加成】")
	this.Attri1 = fmt.Sprintf("%s-%s", this.Attri1, detal1)
	this.Attri2 += detal2
}

func (this *Originator) ShowState() {
	fmt.Println("当前状态为:攻击方式:", this.Attri1, ", 造成伤害为:", this.Attri2)
}

func (this *Originator) SaveStateMemento() Memento {
	stateStr := fmt.Sprintf("%s:%v", this.Attri1, this.Attri2)
	return Memento{
		State: stateStr,
	}
}

func (this *Originator) LoadStateMemento(memento Memento) {
	splitStr := strings.Split(memento.State, ":")
	this.Attri1 = splitStr[0]
	this.Attri2, _ = strconv.ParseInt(splitStr[1], 10, 64)
}

备忘录类:

type Memento struct {
	State string
}

func (this Memento) GetState() string {
	return this.State
}

负责人类:

type Caretaker struct {
	mementoList []Memento
}

func (this *Caretaker) AddMemento(memento Memento) {
	this.mementoList = append(this.mementoList, memento)
}

func (this Caretaker) GetMemento(index int64) Memento {
	return this.mementoList[index]
}

func NewCaretaker() Caretaker {
	return Caretaker{
		mementoList: []Memento{},
	}
}

测试:

package main

import (
	"DemoProject/design/base23/memento"	// 根据自己的项目路径定制
	"fmt"
)

func main() {
	// memento
	fmt.Println("【游戏开始,初始化角色信息...】")

	originator := memento.Originator{
		Attri1: "平A",
		Attri2: 10,
	}
	originator.ShowState()

	caretaker := memento.NewCaretaker()
	caretaker.AddMemento(originator.SaveStateMemento())

	originator.DoAction("附带火焰伤害", 80)
	originator.ShowState()

	fmt.Println("【挑战Boss失败,角色属性重置...】")
	originator.LoadStateMemento(caretaker.GetMemento(0))
	originator.ShowState()
}

注意事项:

备忘录模式 给用户提供了一种 可以恢复状态 的机制,
可以使用户能够比较方便地回到 某个历史的状态

实现了 信息的封装,使得用户不需要关心 状态的保存 细节

如果类的成员变量过多,势必会占用比较大的资源
而且每一次保存都会消耗一定的内存, 这个需要注意
适用的应用场景:

1、后悔药
2、打游戏时的存档
3、Windows 里的 ctrl + z
4、Browser 中的后退
5、数据库的 事务管理

为了 节约内存备忘录模式 可以和 原型模式 配合使用

posted @ 2021-12-17 15:38  在下右转,有何贵干  阅读(84)  评论(0)    收藏  举报