现在聊聊Go里头的备忘录模式,这个可以用来对付复杂业务功能里的“暂存”问题。听上去陌生,实际挺简单。您细看下去。
假设你手头有个用户注册的功能,你要一边保存用户填的信息,一边可以随时回去修改。好比写作文打草稿,写了点,备份一下,怕写错了又能退回去。软件里这个就叫“状态的保存与恢复”。复杂点讲是备忘录模式,其实不少系统你都见过的,就是个带撤销功能的设计。
Go语言简单直接,符合这个模式的需求。所以实现起来得心应手。你先想一个场景,有一页面,用户资料分几步填完。他每填一步,点了“保存并继续”,要是有个状况,想退回去改,这就用得上备忘录模式了。不复杂吧。写这玩意,要做这么几件事:一个是“发起人”,保存用户数据状态的角色,一个是“备忘录”,专门把每次的状态都记录下来。还有“管理者”,记录啥时候存的啥状态,且帮你找到某个状态的副本。
假设一个用户结构体叫User
,你自己大概写这么个结构:
go
type User struct {
Name string
Age int
Address string
}
然后你得有个“备忘录”对象:
go
type Memento struct {
user User
}
别急,下面是个核心概念,“管理者”和“发起人”都得动起来。管理者代码大差不差:
go
type Caretaker struct {
mementos []Memento
}
加点功能,能存能取:
go
func (c *Caretaker) AddMemento(m Memento) {
c.mementos = append(c.mementos, m)
}
func (c *Caretaker) GetMemento(index int) Memento {
return c.mementos[index]
}
接着来到重要的点,Originator
角色(就是用户每次操作的东西)要有的功能是“打包”状态:
go
type Originator struct{
user User
}
func(o *Originator)CreateMemento() Memento {
return Memento{user: o.user}
}
func(o *Originator)SetMemento(m Memento){
o.user = m.user
}
现在用户填表改数据的操作能顺畅了,他可以往前看改动,当然错误数据改回去也可以。你只需要动“管理者”里头那个存储状态列表,几次修改都记下来,完事一调就能还原某次状态。写一功能验证一下是这样的:
go
func main(){
user := User{Name:"张三", Age:25, Address:"北京"}
originator := Originator{user: user}
caretaker := Caretaker{}
// 保存状态
caretaker.AddMemento(originator.CreateMemento())
// 假设修改了数据
originator.user.Name ="李四"
caretaker.AddMemento(originator.CreateMemento())
// 接着要还原某个历史状态
originator.SetMemento(caretaker.GetMemento(0))
fmt.Println(originator.user)// 数据恢复到“张三”状态
}
悟到点什么了吧,其实原理就这么多。没啥神话。无论是几次填写表单,因有这备忘录机制,状态追溯回去给业务捋直了变得很自然。当年工程师也想打草稿吧,想把每一步的前因后果讲清楚,用户许多场景都恨不得照这设计基础走。外表千变万化,底子有点朴素里透着的劲道。随着系统的需求加深,加几层额外处理措施也很方便。