Memento(备忘录) — 对象行为型模式
在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将对象恢复到原先保存的状态。
适用场景
- 必须保存一个对象在某个时刻的(部分)状态,这样以后需要时它才能恢复到先前的状态。
- 如果一个接口让其他对象直接得到这些状态,将会暴露对象的实现细节并破坏对象的封装性。
UML 图
-
Memento(备忘录)
- 备忘录存储原发器对象的内部状态。原发器根据需要决定备忘录存储原发器的那些内部状态。
- 防止原发器意外的启发对象访问备忘录。备忘录实际上有两个接口。管理者(caretaker)只能看到备忘录的窄接口 — 它只能将备忘录传递给其他对象。相反,原发器能够看到一个宽接口,允许它访问返回到先前状态所需的所有数据。理想情况是只允许生成本备忘录的的那个原发器访问本备忘录的内部状态。
-
Originator(原发器)
- 原发器创建一个备忘录,用以记录当前时刻它的内部状态。
- 使用备忘录恢复内部状态
-
Caretaker(管理者)
- 负责保存好备忘录。
- 不能对备忘录的内容进行操作或检查。
效果
- 保持封装边界:使用备忘录可以避免暴露一些只应由原发器管理却又必须存储在原发器之外的信息。该模式把可能很复杂的 Originator 的内部信息对其他对象屏蔽起来,从而保持了封装边界。
- 使用备忘录可能代价很高:如果原发器在生成备忘录时必须拷贝并存储大量的信息,或者客户非常频繁地创建备忘录和恢复原发器状态,可能会导致非常大的开销。除非封装和恢复 Originator 状态的开销不大,否则该模式可能并不合适。
实现
# 发起人类
class Originator(object):def __init__(self, state):self.state = statedef create_memento(self):return Memento(self.state)def set_memento(self, memento):self.state = memento.statedef show(self):print("当前状态 ", self.state)# 备忘录类
class Memento(object):def __init__(self, state):self.state = state# 管理者类
class Caretaker(object):def __init__(self, memento):self.memento = memento
client
if __name__ == "__main__":# 初始状态originator = Originator(state='On')originator.show()# 备忘录caretaker = Caretaker(originator.create_memento())# 修改状态originator.state = 'Off'originator.show()# 复原状态originator.set_memento(caretaker.memento)originator.show()"""output: 当前状态 On 当前状态 Off 当前状态 On """