美文网首页
设计模式——备忘录模式

设计模式——备忘录模式

作者: DevilRoshan | 来源:发表于2020-10-31 02:23 被阅读0次

    什么是备忘录模式?

    在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存着这个状态。这样以后就可将该对象恢复到原先保存的状态。

    实现

    // 游戏角色
    type GameRole struct {
        Vit int // 生命力
        Atk int // 攻击力
        Def int // 防御力
    }
    
    func NewGameRole() *GameRole {
        return &GameRole{}
    }
    
    func (this *GameRole) SetVit(vit int) {
        this.Vit = vit
    }
    
    func (this *GameRole) SetAtk(atk int) {
        this.Atk = atk
    }
    
    func (this *GameRole) SetDef(def int) {
        this.Def = def
    }
    
    func (this *GameRole) GetVit() int {
        return this.Vit
    }
    
    func (this *GameRole) GetAtk() int {
        return this.Atk
    }
    
    func (this *GameRole) GetDef() int {
        return this.Def
    }
    
    //状态显示
    func (this *GameRole) StateDisplay() {
        fmt.Println("角色当前状态:")
        fmt.Println("体力:", this.Vit)
        fmt.Println("攻击力:", this.Atk)
        fmt.Println("防御力: ", this.Def)
        fmt.Println("--------------------------")
    }
    
    // 初始值
    func (this *GameRole) GetInitState() {
        this.Vit = 100
        this.Atk = 100
        this.Def = 100
    }
    
    // 战斗后
    func (this *GameRole) AfterFight() {
        this.Vit = 0
        this.Atk = 0
        this.Def = 0
    }
    
    // 保存角色状态
    func (this *GameRole) SaveState(vit, atk, def int) RoleStateMemento {
        return NewRoleStateMemento(vit, atk, def)
    }
    
    // 恢复角色状态
    func (this *GameRole) RecoveryState(memento RoleStateMemento) {
        this.Vit = memento.GetVit()
        this.Atk = memento.GetAtk()
        this.Def = memento.GetDef()
    }
    
    // 角色状态存储
    type RoleStateMemento struct {
        Vit int // 生命力
        Atk int // 攻击力
        Def int // 防御力
    }
    
    func NewRoleStateMemento(vit, atk, def int) RoleStateMemento {
        return RoleStateMemento{Vit: vit, Atk: atk, Def: def}
    }
    
    func (this *RoleStateMemento) SetVit(vit int) {
        this.Vit = vit
    }
    
    func (this *RoleStateMemento) SetAtk(atk int) {
        this.Atk = atk
    }
    
    func (this *RoleStateMemento) SetDef(def int) {
        this.Def = def
    }
    
    func (this *RoleStateMemento) GetVit() int {
        return this.Vit
    }
    
    func (this *RoleStateMemento) GetAtk() int {
        return this.Atk
    }
    
    func (this *RoleStateMemento) GetDef() int {
        return this.Def
    }
    
    // 角色状态管理
    type RoleStateCaretaker struct {
        memento RoleStateMemento
    }
    
    func (this *RoleStateCaretaker) GetMemento() RoleStateMemento {
        return this.memento
    }
    
    func NewRoleStateCaretaker() *RoleStateCaretaker {
        return &RoleStateCaretaker{}
    }
    
    func (this *RoleStateCaretaker) SetMemento(memento RoleStateMemento) {
        this.memento = memento
    }
    
    func TestNewRoleStateCaretaker(t *testing.T) {
        // 初始化
        gameRole := NewGameRole()
        gameRole.GetInitState()
        gameRole.StateDisplay()
    
        // 保存进度
        caretaker := NewRoleStateCaretaker()
        caretaker.SetMemento(gameRole.SaveState(44, 55, 66))
    
        // 打BOSS失败
        gameRole.AfterFight()
        gameRole.StateDisplay()
    
        // 恢复状态
        gameRole.RecoveryState(caretaker.GetMemento())
        gameRole.StateDisplay()
    }
    // === RUN   TestNewRoleStateCaretaker
    // 角色当前状态:
    // 体力: 100
    // 攻击力: 100
    // 防御力:  100
    // --------------------------
    // 角色当前状态:
    // 体力: 0
    // 攻击力: 0
    // 防御力:  0
    // --------------------------
    // 角色当前状态:
    // 体力: 44
    // 攻击力: 55
    // 防御力:  66
    // --------------------------
    // --- PASS: TestNewRoleStateCaretaker (0.00s)
    // PASS
    

    优点

    • 给用户提供了一种可以恢复状态的机制,可以使用能够比较方便地回到某个历史的状态;
    • 实现了信息的封装,使得用户不需要关心状态的保存细节。

    缺点

    • 消耗资源。

    使用场景

    • 需要保存和恢复数据的相关场景;
    • 提供一个可回滚的操作,如ctrl+z、浏览器回退按钮、Backspace键等;
    • 需要监控的副本场景。

    应用实例

    • 游戏存档,悔棋;
    • 数据库事务回滚。

    注意

    • 为了符合迪米特法则,需要有一个管理备忘录的类;
    • 不要在频繁建立备份的场景中使用备忘录模式。为了节约内存,可使用原型模式+备忘录模式。

    相关文章

      网友评论

          本文标题:设计模式——备忘录模式

          本文链接:https://www.haomeiwen.com/subject/befrvktx.html