备忘录模式

解释:

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

结构图:

  

  Originator(发起人),可根据需要决定Memento存储Originator的哪些内部状态。

  

  Memento(备忘录),有两个接口,Caretaker只能看到备忘录的窄接口,他只能将备忘录传递给其他对象。Originator能够看到一个宽接口,允许将它访问返回到先前状态所需的所有数据。

  

  

  Caretaker(管理者),不能对备忘录的内容进行操作、检查。

  

  客户端:

  

优点:

  保存的细节封装在了Memento中,修改、添加、删除不会影响客户端代码。

缺点:

  状态需要完整存储到Memento中,如果状态数据很大、很多,则Memento对象会非常耗内存。不是用的越多越好。

使用环境、场合:

  功能复杂,但需要维护、记录属性历史的类,或需要保存一部分属性历史的类。

  Originator可以根据保存的Memento信息还原到前一状态。

  使用命令模式的系统中,需要实现命令的撤销功能,可以使用备忘录模式来存储可撤销操作的状态。

  对象的内部信息必须保存在对象以外的地方,但必须由对象自己读取。使用备忘录模式可以把复杂的对象内部信息对其他的对象屏蔽起来,从而可以恰当第保持封装的边界。

  当状态改变时,有可能这个状态会撤销,导致无效,这时可以使用Memento将状态复原。

使用建议:

  保存全部信息时,用Originator实例来做状态备份可以考虑,但是用clone的方式来实现状态备份可能是更好的办法。缺点是:对上层应用开放了Originator的全部(public)接口,不合适。

  不需要备份全部状态信息时,只是部分,应该有一个独立的Memento类,只拥有需要保存的信息的属性。

应用:

  1.游戏状态的各种参数存储,以便日后读取。(保存在磁盘上)

  2.常规应用:悔棋、文档撤销操作、网页后退,频繁、简单的恢复。(保存在内存中)

示例:

  

  客户端代码:

  

  对比:

  客户端暴露了实现细节,不可取。

  

  

  

扩展:

  代码无错未必优。

  不能将功能细节暴露给客户端。否则,客户端责任太大。增加、修改时困难。

原文地址:https://www.cnblogs.com/panpanwelcome/p/5590097.html