设计模式学习笔记--Memento 备忘录模式
在软件的构建过程中,某些对象的状态在转换过程中,可能由于某种需要,要求程序能够回溯到对象之前某个点时的状态,如果使用一些公有接口来让其他对象得到对象的状态,便会暴露对象的细节实现。
如何实现对象状态的良好保存与恢复?但同时又不会因此而破坏对象本身的封装性。
Memento 备忘录模式提供解决途径,它在不破坏封装性的前提下,捕获一个对象的内部状态,并在这个对象之外保存这个状态。这样就可以将对象恢复到原先保存的状态。《设计模式》— GOF
Memento备忘录模式UML图如下:
主要角色:
1、原发器角色Originator:它是我们关注的对象,我们需要保存和回溯的状态就是它的状态。我们需要在它内部创建备忘录对象并利用备忘录对象保存我们需要保存的状态值,同时它还需要提供一种手段来恢复我们以前保存的状态值.
2、备忘录对象Memento:它用于在不破坏封装性的前提下,捕获一个Originator的内部状态,并在备忘录对象Memento中保存这个状态。(Caretaker:用于防止原发器以外的对象访问备忘录对象,保证备忘录对象的安全性)。
下面我们用代码来示例,程序如下:
一、备忘录模式思路示例
1、原发器角色Originator
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
2、备忘录对象Memento
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
3、Caretaker
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
4、客户端应用
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
二、在客户对象上使用备忘录模式
1、原发器角色Originator:ClientsOriginator
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
2、备忘录对象Memento:ClientsMemento
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
3、Caretaker:ClientMemory
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
4、客户端应用
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
运行效果如下:
总结:
备忘录存储原发器(Originator)对象的内部状态,在需要时恢复原发器状态。Memento模式适用于由原发器管理,却又必须存储在原发器之外的信息
在实现Memento模式中,要防止原发器以外的对象方位备忘录对象,备忘录对象有两个接口,一个为原发器使用的宽接口,一个为其他对象使用的窄接口。在上面的例子中Originator对于Memento看到是宽接口,即SetState方法,而用户端看到的是窄接口,即Memento的构造函数和Creatememento、SetMemento方法。
在实现Memento模式时,要考虑拷贝对象状态的效率问题,如果对象开销比较大,可以采用某种增量式改变来跟进Memnto模式