设计模式之 Memento 备忘录模式:Swift 实现

Memento Mode 备忘录模式

使用绘画板之类的软件时,其中有“撤销”的操作,即是返回编辑内容的上一步,多次点击可以撤销到前几步,这里涉及到“历史记录”的概念,前几次操作是存放在历史记录中,撤销的时候即是从历史记录中取出最近的一次操作,作为当前操作,这就是备忘录模式的具体应用。所以接下来,让我们来理解备忘录模式的实现吧!

It allow to save or recover the object state before without expose the object’s implemented detail. The originator can create the snapshot of itself and can restore the snapshot when it need. The memento is a value object of the originator’s snapshot state, it’s built by the initializer and pass the information by only one time. The caretaker can only use the originator’s makeMemento() and restore().

它允许在不暴露对象实现细节的情况下,保存和恢复对象之前的状态。原发器可以创建它自己的快照并且在需要的时候恢复快照到自身。备忘录是一个用于存放原发器快照状态的值对象,它只通过构造函数传递状态信息。负责人只可以使用原发器的 “创建快照” 和 “恢复状态” 的方法。

备忘录模式

// Originator
protocol Animal {
    func getMemento() -> Memento
}

// Memento
protocol Memento {
    func restore()
}

// Concrete originator
class Dog: Animal {
    private var age: Int
    private var weight: Float
    private var legCount: Int
    
    init(age: Int, weight: Float, legCount: Int) {
        self.age = age
        self.weight = weight
        self.legCount = legCount
    }
    func getMemento() -> Memento {
        return DogData(dog: self, age: age, weight: weight, legCount: legCount)
    }
    func setAge(age: Int) {
        self.age = age
    }
    func setWeight(weight: Float) {
        self.weight = weight
    }
    func setLegCount(legCount: Int) {
        self.legCount = legCount
    }
    
    func info() -> String {
        return "age: \(age) weight: \(weight) legCount: \(legCount)"
    }
}

// Concrete memento
class DogData: Memento {
    private var age: Int
    private var weight: Float
    private var legCount: Int
    
    private var dog: Dog?
    
    init(dog: Dog, age: Int, weight: Float, legCount: Int) {
        self.dog = dog
        self.age = age
        self.weight = weight
        self.legCount = legCount
    }
    
    // restore data from memento to originator
    func restore() {
        dog?.setAge(age: age)
        dog?.setWeight(weight: weight)
        dog?.setLegCount(legCount: legCount)
    }
    
}

// CareTaker
class Recored {
    var dog: Dog
    var history: [Memento] = []
    init(dog: Dog) {
        self.dog = dog
    }
    func save() {
        var backup = dog.getMemento()
        history.append(backup)
        if (history.count > 10) {
            history.remove(at: 0)
        }
    }
    
	//  use stack structure to store 
    func undo() {
        if history.count <= 0 {
            return 
        }
        var data = history[history.count - 1]
        data.restore()
        history.remove(at: history.count - 1)
    }
    
}

let dog = Dog(age: 2, weight: 15, legCount: 4)
let record = Recored(dog: dog)
record.save()
print(dog.info())

dog.setAge(age: 4)
dog.setWeight(weight: 20)
print(dog.info())

record.undo()
print(dog.info())

备忘录模式,有原发器(带有数据的类本身)、负责记录者(持有原发器的引用和 “历史记录数组” 的引用)。
上方代码中,Dog 是原发器,DogData 是备忘对象,Record 是备忘录负责者。加入记录时,dog 借助自身的 save 方法生成一个备忘对象(把原发器引用给备忘对象,有利于备忘对象回忆)dogData,将备忘对象存入备忘录 record;恢复记录时,从备忘录中取出最近的一个备忘对象,调用备忘对象的 restore 方法,把备忘对象自身所带的数据恢复到自身持有的原发器引用所指的对象。

备忘对象存有原发器的副本和引用,用来存入备忘录或者从备忘录拿出后恢复到原发器

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值