
项目结构:

/*
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Memento Pattern备忘录模式
# Author : geovindu,Geovin Du 涂聚文.
# IDE : goLang 2024.3.6 go 26.2
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/4/26 15:22
# User : geovindu
# Product : GoLand
# Project : godesginpattern
# File : memento.go
*/
package entity
// Memento 备忘录顶层接口
// 企业级规范:面向接口编程,方便扩展不同类型备忘录
type Memento interface {
GetID() string // 唯一标识
}
// ==============================================
// 以下为私有实现:外部包无法访问,保证封装性
// ==============================================
// bizMemento 业务备忘录(私有结构体,外部无法读写状态)
type bizMemento struct {
id string // 快照ID
stateData []byte // 序列化后的原发器状态(二进制,绝对安全)
}
func (m *bizMemento) GetID() string {
return m.id
}
// NewBizMemento 创建备忘录(仅内部包可调用)
func NewBizMemento(id string, state []byte) Memento {
return &bizMemento{id: id, stateData: state}
}
// GetState 获取状态(仅内部包可调用)
func (m *bizMemento) GetState() []byte {
return m.stateData
}
/*
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Memento Pattern备忘录模式
# Author : geovindu,Geovin Du 涂聚文.
# IDE : goLang 2024.3.6 go 26.2
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/4/26 15:23
# User : geovindu
# Product : GoLand
# Project : godesginpattern
# File : originator.go
*/
package entity
import "encoding/json"
// Originator 原发器接口
// 所有需要备份/回退的对象都必须实现该接口
type Originator interface {
CreateMemento(id string) (Memento, error) // 创建快照
RestoreFromMemento(m Memento) error // 从快照恢复
}
// ==============================================
// 业务原发器示例:企业配置(可替换为订单/设备/商品)
// ==============================================
// EnterpriseConfig 企业配置(真实业务可替换为任意实体)
type EnterpriseConfig struct {
CompanyID string `json:"company_id"` // 企业ID
Name string `json:"name"` // 企业名称
Version int `json:"version"` // 配置版本
Status string `json:"status"` // 状态:enable/disable
Balance float64 `json:"balance"` // 账户余额
}
// CreateMemento 创建备忘录:序列化状态为二进制(安全封装)
func (e *EnterpriseConfig) CreateMemento(id string) (Memento, error) {
// 序列化为JSON二进制(可替换为Protobuf/gob)
stateBytes, err := json.Marshal(e)
if err != nil {
return nil, err
}
return NewBizMemento(id, stateBytes), nil
}
// RestoreFromMemento 从备忘录恢复状态
func (e *EnterpriseConfig) RestoreFromMemento(m Memento) error {
bizM := m.(*bizMemento)
// 反序列化
return json.Unmarshal(bizM.GetState(), e)
}
// 业务方法:修改状态
func (e *EnterpriseConfig) UpdateBalance(balance float64) {
e.Balance = balance
e.Version++
}
func (e *EnterpriseConfig) UpdateStatus(status string) {
e.Status = status
e.Version++
}/*
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Memento Pattern备忘录模式
# Author : geovindu,Geovin Du 涂聚文.
# IDE : goLang 2024.3.6 go 26.2
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/4/26 15:23
# User : geovindu
# Product : GoLand
# Project : godesginpattern
# File : memento_store.go
*/
package repository
import (
"errors"
"godesginpattern/memento/entity"
)
// MementoStore 备忘录存储接口
// 支持扩展:内存存储、Redis存储、MySQL存储
type MementoStore interface {
Save(m entity.Memento) error // 保存备忘录
Get(id string) (entity.Memento, error) // 获取备忘录
List() []entity.Memento // 获取所有快照
}
// ==============================================
// 默认实现:内存存储(生产可替换)
// ==============================================
type memoryStore struct {
mementos map[string]entity.Memento
}
func NewMemoryStore() MementoStore {
return &memoryStore{
mementos: make(map[string]entity.Memento),
}
}
func (m *memoryStore) Save(me entity.Memento) error {
m.mementos[me.GetID()] = me
return nil
}
func (m *memoryStore) Get(id string) (entity.Memento, error) {
me, ok := m.mementos[id]
if !ok {
return nil, errors.New("备忘录不存在")
}
return me, nil
}
func (m *memoryStore) List() []entity.Memento {
list := make([]entity.Memento, 0, len(m.mementos))
for _, v := range m.mementos {
list = append(list, v)
}
return list
}/*
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Memento Pattern备忘录模式
# Author : geovindu,Geovin Du 涂聚文.
# IDE : goLang 2024.3.6 go 26.2
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/4/26 15:23
# User : geovindu
# Product : GoLand
# Project : godesginpattern
# File : memento_service'.go
*/
package service
import (
"godesginpattern/memento/entity"
"godesginpattern/memento/repository"
)
// MementoService 备忘录服务(Caretaker 负责人)
// 职责:只管理备忘录的保存、获取、回滚,不修改任何业务数据
type MementoService struct {
store repository.MementoStore
}
func NewMementoService(store repository.MementoStore) *MementoService {
return &MementoService{store: store}
}
// Backup 备份原发器状态
func (s *MementoService) Backup(originator entity.Originator, snapshotID string) error {
m, err := originator.CreateMemento(snapshotID)
if err != nil {
return err
}
return s.store.Save(m)
}
// Rollback 回滚到指定快照
func (s *MementoService) Rollback(originator entity.Originator, snapshotID string) error {
m, err := s.store.Get(snapshotID)
if err != nil {
return err
}
return originator.RestoreFromMemento(m)
}
// ListSnapshots 获取所有备份列表
func (s *MementoService) ListSnapshots() []entity.Memento {
return s.store.List()
}调用:
/*
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Memento Pattern备忘录模式
# Author : geovindu,Geovin Du 涂聚文.
# IDE : goLang 2024.3.6 go 26.2
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/4/26 18:54
# User : geovindu
# Product : GoLand
# Project : godesginpattern
# File : mementobll.go
memento/
├── go.mod # 项目模块
├── internal/ # 内部包(外部不可访问)
│ ├── entity/ # 实体层:原发器、备忘录(核心数据)
│ │ ├── memento.go # 备忘录接口 + 实现
│ │ └── originator.go # 原发器接口 + 业务实体
│ ├── repository/ # 存储层:备忘录持久化/存储
│ │ └── memento_store.go
│ └── service/ # 服务层:负责人(Caretaker)核心逻辑
│ └── memento_service.go
└── cmd/ # 应用层:入口、测试用例
└── main.go
*/
package bll
import (
"fmt"
"godesginpattern/memento/entity"
"godesginpattern/memento/repository"
"godesginpattern/memento/service"
)
func MementoMain() {
// ===================== 1. 初始化依赖(DI依赖注入) =====================
store := repository.NewMemoryStore() // 存储层
memoSvc := service.NewMementoService(store) // 服务层
// ===================== 2. 创建原发器(企业配置) =====================
config := &entity.EnterpriseConfig{
CompanyID: "COMPANY_001",
Name: "科技有限公司",
Version: 1,
Status: "enable",
Balance: 100000.00,
}
fmt.Println("===== 初始状态 =====")
printConfig(config)
// ===================== 3. 备份 V1 版本 =====================
_ = memoSvc.Backup(config, "SNAPSHOT_V1")
fmt.Println("\n✅ 已备份 SNAPSHOT_V1")
// ===================== 4. 修改状态 =====================
config.UpdateBalance(80000.00)
config.UpdateStatus("disable")
fmt.Println("\n===== 修改后状态 V2 =====")
printConfig(config)
// ===================== 5. 备份 V2 版本 =====================
_ = memoSvc.Backup(config, "SNAPSHOT_V2")
fmt.Println("\n✅ 已备份 SNAPSHOT_V2")
// ===================== 6. 再次修改 =====================
config.UpdateBalance(50000.00)
fmt.Println("\n===== 二次修改状态 =====")
printConfig(config)
// ===================== 7. 回滚到 V1 =====================
fmt.Println("\n🔄 回滚到 SNAPSHOT_V1")
_ = memoSvc.Rollback(config, "SNAPSHOT_V1")
printConfig(config)
// ===================== 8. 回滚到 V2 =====================
fmt.Println("\n🔄 回滚到 SNAPSHOT_V2")
_ = memoSvc.Rollback(config, "SNAPSHOT_V2")
printConfig(config)
}
// printConfig 打印配置状态
func printConfig(c *entity.EnterpriseConfig) {
fmt.Printf("企业ID:%s\n名称:%s\n版本:%d\n状态:%s\n余额:%.2f\n",
c.CompanyID, c.Name, c.Version, c.Status, c.Balance)
}输出:
