设计模式-14.备忘录模式

307 阅读1分钟

一句话总结

备忘录模式是在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样可以在之后将对象恢复到保存的状态。

需求

李逍遥要打Boss了,但是打之前没有保存进度,没打过Boss后,只能从头再来。现在要设计一个存档系统。

Code V1.0

static func main() {
    let lixiaoyao = GameRole()
    lixiaoyao.initState()
    lixiaoyao.stateDisplay()

    //保存进度
    let backup = GameRole()
    backup.vit = lixiaoyao.vit
    backup.atk = lixiaoyao.atk
    backup.def = lixiaoyao.def

    //大战boss
    lixiaoyao.fight()
    lixiaoyao.stateDisplay()

    //恢复进度
    lixiaoyao.vit = backup.vit
    lixiaoyao.atk = backup.atk
    lixiaoyao.def = backup.def

    lixiaoyao.stateDisplay()
}

class GameRole {
    var vit: Int = 0
    var atk: Int = 0
    var def: Int = 0

    func stateDisplay() {
        print("角色当前状态:")
        print("体力:\(vit)")
        print("攻击力:\(atk)")
        print("防御力:\(def)")
        print("")
    }

    func initState() {
        vit = 100
        atk = 100
        def = 100
    }

    func fight() {
        vit = 0
        atk = 0
        def = 0
    }

}

备忘录模式示例code

static func main() {
    let o = Originator()
    o.state = "On"
    o.show()
    
    let c = Caretaker()
    c.memento = o.createMemento()
    
    o.state = "off"
    o.show()
    
    o.setMemento(memento: c.memento)
    o.show()
}

class Originator {
    var state = ""
    
    func createMemento() -> Memento {
        Memento(state: state)
    }
    
    func setMemento(memento: Memento) {
        state = memento.state
    }
    
    func show() {
        print("state = \(state)")
    }
}

class Memento {
    var state: String
    
    init(state: String) {
        self.state = state
    }
}

class Caretaker {
    var memento = Memento(state: "")
}

Code V2.0

用备忘录模式实现这个需求

static func main() {
    let lixiaoyao = GameRole()
    lixiaoyao.stateDisplay()
    
    //保存进度
    let roleStateCaretaker = RoleStateCaretaker()
    roleStateCaretaker.roleStateMemento = lixiaoyao.createRoleStateMemento()
    
    //大战boss
    lixiaoyao.fight()
    lixiaoyao.stateDisplay()
    
    //恢复进度
    lixiaoyao.recoveryState(roleStateMemento: roleStateCaretaker.roleStateMemento)
    
    lixiaoyao.stateDisplay()
}

class GameRole {
    var vit: Int = 100
    var atk: Int = 100
    var def: Int = 100
    
    func createRoleStateMemento() -> RoleStateMemento {
        RoleStateMemento(vit: vit, atk: atk, def: def)
    }
    
    func recoveryState(roleStateMemento: RoleStateMemento) {
        vit = roleStateMemento.vit
        atk = roleStateMemento.atk
        def = roleStateMemento.def
    }
    
    func stateDisplay() {
        print("角色当前状态:")
        print("体力:\(vit)")
        print("攻击力:\(atk)")
        print("防御力:\(def)")
        print("")
    }
    
    func fight() {
        vit = 0
        atk = 0
        def = 0
    }
}

class RoleStateMemento {
    var vit: Int
    var atk: Int
    var def: Int
    
    init(vit: Int, atk: Int, def: Int) {
        self.vit = vit
        self.atk = atk
        self.def = def
    }
}

class RoleStateCaretaker {
    var roleStateMemento = RoleStateMemento(vit: 0, atk: 0, def: 0)
}

何时使用?

适用功能比较复杂,需要记录和恢复属性历史的类。