风雨同行 发表于 2025-3-9 08:04:40

Golang学习笔记_45——备忘录模式

Golang学习笔记_42——迭代器模式
Golang学习笔记_43——责任链模式
Golang学习笔记_44——下令模式


一、核心概念

1. 界说

备忘录模式是一种行为型计划模式,通过在不粉碎对象封装性的前提下捕获和存储对象内部状态,实现状态的可追溯恢复机制。其核心特点包括:
• 状态封装:将对象状态隔离在专用备忘录对象中
• 汗青回溯:支持任意时间点的状态版本恢复
• 权限隔离:状态存储与恢复操纵限定在特定对象间
2. 办理的题目

• 状态不可逆:缺乏标准化的撤销/恢复机制
• 数据袒露风险:直接访问对象内部状态粉碎封装性
• 版本管理复杂:多版本状态存储与检索困难
3. 核心脚色

脚色作用Originator创建并管理备忘录的生命周期,维护内部状态Memento存储Originator内部状态的安全容器Caretaker备忘录的存储管理者,维护汗青状态记录栈 4. 类图

https://i-blog.csdnimg.cn/direct/b4ab8791034d45d1befb5a2458dc35cb.png
@startuml
class Originator {
    - state: string
    + CreateMemento(): Memento
    + Restore(m: Memento)
}

class Memento {
    - state: string
    + GetState(): string
    + SetState(s: string)
}

class Caretaker {
    - history: []Memento
    + Save(m: Memento)
    + Retrieve(index int): Memento
}

Originator --> Memento
Caretaker --> Memento

note right of Originator::CreateMemento
    创建包含当前状态的备忘录
    仅Originator可访问完整数据
end note
@enduml
二、特点分析

优点

[*]封装保护:严格限定状态访问权限
[*]简化恢复:标准化状态回滚操纵流程
[*]版本控制:支持多时间点状态快照管理
缺点

[*]内存消耗:大对象频繁快照导致资源占用
[*]性能消耗:深拷贝复杂对象时效率降落
[*]版本冲突:多版本管理可能引发状态不一致
三、适用场景

1. 文档编辑器

type EditorMemento struct {
    content string
}

type TextEditor struct {
    content string
}

func (e *TextEditor) Save() *EditorMemento {
    return &EditorMemento{content: e.content}
}

func (e *TextEditor) Restore(m *EditorMemento) {
    e.content = m.content
}
2. 游戏存档系统

type GameSave struct {
    level   int
    weapons []string
}

type PlayerState struct {
    current *GameSave
}

func (p *PlayerState) QuickSave() *GameSave {
    return &GameSave{
      level:   p.current.level,
      weapons: append([]string{}, p.current.weapons...),
    }
}
3. 配置管理系统

type ConfigSnapshot struct {
    version string
    configmapinterface{}
}

func RollbackConfig(snapshots []*ConfigSnapshot, targetVer string) error {
    // 实现版本检索与配置回滚
}
四、Go语言实现示例

https://i-blog.csdnimg.cn/direct/2d41498fae4c401c8770cf4e5caa4f9b.png
完整实现代码
package memento_demo

import "fmt"

// Memento 备忘录
type EditorMemento struct {
        content string
}

func (m *EditorMemento) Content() string {
        return m.content
}

// Originator 原发器
type TextEditor struct {
        content string
}

func (e *TextEditor) Write(input string) {
        e.content += input
}

func (e *TextEditor) Save() *EditorMemento {
        return &EditorMemento{content: e.content}
}

func (e *TextEditor) Restore(m *EditorMemento) {
        e.content = m.Content()
}

// Caretaker 管理者
type HistoryKeeper struct {
        saves []*EditorMemento
}

func (h *HistoryKeeper) Push(m *EditorMemento) {
        h.saves = append(h.saves, m)
}

func (h *HistoryKeeper) Pop() *EditorMemento {
        if len(h.saves) == 0 {
                return nil
        }
        last := h.saves
        h.saves = h.saves[:len(h.saves)-1]
        return last
}

// 客户端使用示例
func ExampleUsage() {
        editor := &TextEditor{}
        history := &HistoryKeeper{}

        // 编辑操作
        editor.Write("Hello")
        history.Push(editor.Save())

        editor.Write(" World")
        fmt.Println("Current:", editor.content)

        // 撤销操作
        if m := history.Pop(); m != nil {
                editor.Restore(m)
        }
        fmt.Println("After Undo:", editor.content)
}
执行结果
=== RUN   TestExampleUsage
Current: Hello World
After Undo: Hello
--- PASS: TestExampleUsage (0.00s)
PASS

五、高级应用

1. 增量快照系统

type DeltaMemento struct {
    timestamp time.Time
    delta   []byte
}

func CreateDeltaSnapshot(prev, current *DocumentState) *DeltaMemento {
    // 计算差异生成增量快照
}
2. 分布式状态同步

type StateSyncService struct {
    snapshots map*NodeState
}

func (s *StateSyncService) RollbackCluster(targetVer int) {
    // 集群级状态回滚实现
}
六、与其他模式对比

模式核心区别典型应用场景下令模式操纵封装 vs 状态存储事务回滚系统原型模式对象克隆 vs 状态保存复杂对象复制状态模式状态转移 vs 状态存档工作流引擎 七、实现建议


[*]状态序列化:使用JSON/gob实现快照长期化func (m *Memento) Serialize() ([]byte, error) {
    return json.Marshal(m)
}

[*]内存优化:采用写时复制技能减少内存占用
[*]版本压缩:定期归并汗青快照减少存储量
[*]访问控制:严格限定Memento的字段可见性
八、典型应用


[*]IDE开发环境:代码修改汗青追溯
[*]区块链系统:区块状态回滚机制
[*]机器学习:模型练习检查点
[*]CI/CD管道:摆设失败快速回退
通过备忘录模式,可以构建具备完善汗青管理本领的系统架构。在Go语言中,建议:


[*]使用布局体嵌套实现宽接口/窄接口
[*]结合channel实现异步快照存储
[*]使用sync.Pool优化频繁创建的备忘录对象

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: Golang学习笔记_45——备忘录模式