“备忘录模式”就这么简单

备忘录模式的官方定义:

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

大白话说:

一个对象中一般都封装了很多属性,这些属性的值会随着程序的运行而变化。当我们需要保存某一时刻对象的某些值的时候,我们就再创建一个对象,将当前对象中的一些属性保存到新的对象中,当我们需要恢复的时候再从新的对象中取出属性值即可。这种想法就是备忘录模式。

备忘录模式的类图:

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.使用备忘录模式之后,备份数据虽然交给了其他对象保存,但对象的备份操作和还原操作都是通过对象本身的函数实现的,因此体现了封装的思想。

什么时候使用备忘录模式?

当一个对象需要记录其历史属性,并且需要记录的属性是所有属性的一部分时,可以使用备忘录模式记录属性。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏好好学java的技术栈

深入线程Thread类的start()方法和run()方法

java的线程是通过java.lang.Thread类来实现的。VM启动时会有一个由主方法所定义的线程。可以通过创建Thread的实例来创建新的线程。每个线程都...

1170
来自专栏haifeiWu与他朋友们的专栏

Redis协议规范(译文)

Redis客户端使用名为RESP(Redis序列化协议)的协议与Redis服务器进行通信。 虽然该协议是专为Redis设计的,但它可以用于其他CS软件项目的通讯...

1383
来自专栏Redis源码学习系列

Redis源码学习之列表对象

列表对象的底层实现可以是【压缩列表】或者【双端链表】,Redis会通过用户对于压缩列表单个节点值长度(list_max_ziplist_value)和键值对个数...

1872
来自专栏大数据架构

Java进阶(二)当我们说线程安全时,到底在说什么

2334
来自专栏北京马哥教育

ansible之playbook功能简述

playbooks剧本简介 playbooks是ansible更为强大的配置管理组件,实现基于文本文件编排执行的多个任务,且多次重复执行。其是使用YAML(Ye...

3685
来自专栏java 成神之路

JVM 类加载机制深入浅出

27211
来自专栏奔跑的蛙牛技术博客

synchronized 详解

那到底使用synchronized关键字是不是就是一个监视器? 不懂,理解的话可以向我发邮件gaomengjie_1@163.com,我虚心求教

783
来自专栏xingoo, 一个梦想做发明家的程序员

AngularJS API之extend扩展对象

angular.extend(dst,src),在我实验的1.2.16版本上是支持深拷贝的。但是最新的API显示,这个方法是不支持深拷贝的。 另外,第二个参...

18510
来自专栏各种机器学习基础算法

python中关于'gbk' codec can't encode character u'\xxx'的问题

问题: 使用webdriver中获取网页数据流的时候,然后print driver.find_element_by_id('').text,出现如下错误 Uni...

41210
来自专栏SpringBoot

hbiernate validator 校验实体bean工具类

因公司项目需要,我们需要在其他地方对实体类经行校验,所有提取出来一个工具类ValidateUtil

1321

扫码关注云+社区

领取腾讯云代金券