备忘录模式的官方定义:
在不破坏封装性的前提下,获取一个对象的内部状态,并在该对象之外保存这些状态。这样以后就可以通过该对象恢复到原先保存的状态。
大白话说:
一个对象中一般都封装了很多属性,这些属性的值会随着程序的运行而变化。当我们需要保存某一时刻对象的某些值的时候,我们就再创建一个对象,将当前对象中的一些属性保存到新的对象中,当我们需要恢复的时候再从新的对象中取出属性值即可。这种想法就是备忘录模式。
备忘录模式的类图:
1.需要备份的类是Orginator,备份的数据保存在Mementor中,由CareTaker来管理Mementor。
2.Orginator中必须含有两个函数,一个是createMementor(),用来创建Mementor对象,并将需要备份的数据保存到该对象中;另外一个是setMementor(Mementor),用来恢复数据,将传入的Mementor对象中的数据取出来,赋给当前对象中的属性。
不用备忘录模式进行备份对象信息:
调用者使用别人提供给我们的Orginator对象,用着用着我们突然想要保存Orginator对象中的数据了,此时我们一般会再创建个Orginator对象,把需要保存的数据一个个地复制到新的Orginator对象中去。然后当我们需要还原的时候,再将新Orginator对象中的数据一个个拷到旧的Orginator对象中去。
这种方式有个巨大的缺陷:
我们在保存属性的时候需要记住保存了哪些属性,好在还原的时候将这些属性再复制给原来的对象。如果需要保存的属性发生了变化,那么我们还需要修改自己的代码。
使用了备忘录模式的好处:
使用了备忘录模式之后,对方在提供给我们Orginator类的基础上还给我们提供了Mementor、CareTaker类。我们客户端只需要在需要备份的地方调用createMementor()函数,需要还原的地方调用setMementor。如果需要备份的属性发生了变化,那也只是第三方类库Orginator、Mementor进行了修改,对于我们客户端来说,代码不需要任何修改。
备忘录模式与克隆的区别?
有的人说,备忘录模式就是用来保存对象中一些属性,那么当我们需要备份对象中属性的时候完全可以克隆这个对象嘛,何必采用构造这么复杂的备忘录模式呢?
原因有以下几点:
1.进行一次克隆会将对象的全部属性都复制到一个新的对象中去,而当我们仅需要备份对象中一部分属性的时候就只能使用备忘录模式。
PS:在只备份一部分属性的时候也可以新建一个对象,然后把需要备份的属性一一复制给新对象中;然后当还原的时候再一一复制到原本的对象中去。但这样做太烂了!因为客户端在备份的时候必须要记住哪些属性备份了,好在还原的时候还原这些属性。而且当需要备份的属性发生变化的时候,必须修改客户端代码,这很不科学。
2.使用备忘录模式之后,当需要备份的属性发生变化后,只需修改Orginator类和Mementor类,无需修改客户端代码。
3.使用备忘录模式之后,备份数据虽然交给了其他对象保存,但对象的备份操作和还原操作都是通过对象本身的函数实现的,因此体现了封装的思想。
什么时候使用备忘录模式?
当一个对象需要记录其历史属性,并且需要记录的属性是所有属性的一部分时,可以使用备忘录模式记录属性。