原文链接  作者:Pankaj Kumar 译者:f0tlo <1357654289@qq.com>

备忘录模式是一种行为模式。备忘录模式用于保存对象当前状态,并且在之后可以再次使用此状态。备忘录模式实现的方式需要保证,被保存的对象状态不能被对象从外部访问,目的为了被保存的这些对象状态的完整性。

备忘录模式通过两个对象实现:Originator以及Caretaker。Originator类代表了其状态能够被存储并被用于恢复之前的状态,它使用内部类保存对象的状态。此内部类就被叫做备忘录,注意此类是私有的,它不能被其他对象访问。

Caretaker是一个帮助类,它的职责就是通过备忘录帮助Originator存储当前状态或者恢复重建其之前的状态。因为备忘录是Originator的私有类,Caretaker不能访问它,因此它作为一个对象被存储在caretaker中。

现实中最好的例子是文本编辑器,它任何时候都存在已经输入的数据,并且可以使用回退功能恢复之前的存储(写作)状态。我们将实现相同功能并且提供一个任何时候都把输入、存在内容到文件中的工具集,此外,我们也能恢复上一个存储(写作)的状态。为了简单,此处没用更实用任何写入数据到文件的IO操作。

Originator类

package com.journaldev.design.memento;

public class FileWriterUtil {

private String fileName;

private StringBuilder content;

public FileWriterUtil(String file){

this.fileName=file;

this.content=new StringBuilder();

}

@Override

public String toString(){

return this.content.toString();

}

public void write(String str){

content.append(str);

}

public Memento save(){

return new Memento(this.fileName,this.content);

}

public void undoToLastSave(Object obj){

Memento memento = (Memento) obj;

this.fileName= memento.fileName;

this.content=memento.content;

}

private class Memento{

private String fileName;

private StringBuilder content;

public Memento(String file, StringBuilder content){

this.fileName=file;

//notice the deep copy so that Memento and FileWriterUtil content variables don't refer to same object

this.content=new StringBuilder(content);

}

}

}

注意备忘录的内部类及其保存及恢复方法。现在实现Caretaker类

Caretaker类

package com.journaldev.design.memento;

public class FileWriterCaretaker {

private Object obj;

public void save(FileWriterUtil fileWriter){

this.obj=fileWriter.save();

}

public void undo(FileWriterUtil fileWriter){

fileWriter.undoToLastSave(obj);

}

}

注意caretaker对象包含了整个对象形式的存储状态,因此它既不能修改被保存对象又对其结构未知。

备忘录测试类

完整一个简单地测试程序

package com.journaldev.design.memento;

public class FileWriterClient {

public static void main(String[] args) {

FileWriterCaretaker caretaker = new FileWriterCaretaker();

FileWriterUtil fileWriter = new FileWriterUtil("data.txt");

fileWriter.write("First Set of Data\n");

System.out.println(fileWriter+"\n\n");

// lets save the file

caretaker.save(fileWriter);

//now write something else

fileWriter.write("Second Set of Data\n");

//checking file contents

System.out.println(fileWriter+"\n\n");

//lets undo to last save

caretaker.undo(fileWriter);

//checking file content again

System.out.println(fileWriter+"\n\n");

}

}

上述程序的输出如下:

First Set of Data

First Set of Data

Second Set of Data

First Set of Data

此模式简单易实现,但是需要注意的是备忘录类只能被Originator对象访问。在客户端程序中,使用caretaker对象完成保存或恢复originator对象的状态。

另外,如果Originator对象有一些属性不是不可变的,我们需要使用深拷贝或者克隆来避免数据的完整性问题。使用序列化来取得备忘录模式的实现不失为一般方法,而不是为每一个对象创建一个自己的备忘录实现。

此模式的缺点是, 如果Originator对象非常巨大,那么备忘录对象的大小也会被相应增大,因而需要更多的内存空间。

java实现备忘录_JAVA中的备忘录模式实例教程相关推荐

  1. java金字塔程序_Java中的金字塔模式程序

    java金字塔程序 Pattern programs are used a lot in interviews to understand the logical thinking abilities ...

  2. java 设计模式 示例_Java中的状态设计模式–示例教程

    java 设计模式 示例 状态模式是行为设计模式之一 . 当对象根据其内部状态更改其行为时,将使用状态设计模式. 如果必须根据对象的状态更改其行为,则可以在对象中使用状态变量,并使用if-else条件 ...

  3. JAVA中的命令模式实例教程

    原文链接  作者:Pankaj Kumar 译者:f0tlo <1357654289@qq.com> 命令模式是一种行为模式,因此,它处理的是对象的行为.命令模式为系统中不同的对象提供中性 ...

  4. java 静态 编译_Java中的动态和静态编译实例详解

    Java中的动态和静态编译实例详解 首先,我们来说说动态和静态编译的问题. Q: java和javascript有什么区别? 总结了一下:有以下几点吧: 1.首先从运行环境来说java代码是在JVM上 ...

  5. java synchronized 使用_Java中synchronized的使用实例

    Java中synchronized的使用实例 synchronized关键字,代表这个方法加锁,相当于不管哪一个线程(例如线程A),运行到这个方法时,都要检查有没有其它线程B(或者C.D等)正在用这个 ...

  6. 命令模式 java_JAVA中的命令模式实例教程

    原文链接  作者:Pankaj Kumar 译者:f0tlo <1357654289@qq.com> 命令模式是一种行为模式,因此,它处理的是对象的行为.命令模式为系统中不同的对象提供中性 ...

  7. Java中的策略模式实例教程

    策略模式是一种行为模式.用于某一个具体的项目有多个可供选择的算法策略,客户端在其运行时根据不同需求决定使用某一具体算法策略. 策略模式也被称作政策模式.实现过程为,首先定义不同的算法策略,然后客户端把 ...

  8. java 设计模式 示例_Java中的访问者设计模式–示例教程

    java 设计模式 示例 访客模式是行为设计模式之一 . 当我们必须对一组相似类型的对象执行操作时,将使用访问者模式. 借助访问者模式,我们可以将操作逻辑从对象移动到另一个类. 例如,假设有一个购物车 ...

  9. java 观察者模式示例_Java中的观察者设计模式-示例教程

    java 观察者模式示例 观察者模式是行为设计模式之一 . 当您对对象的状态感兴趣并希望在发生任何更改时得到通知时,观察者设计模式很有用. 在观察者模式中,监视另一个对象状态的对象称为Observer ...

最新文章

  1. 斯坦佛编程教程-Unix编程工具(四)
  2. 避免CONVT_NO_NUMBER的Runtime Errors
  3. VTK:网格之TableBasedClipDataSetWithPolyData
  4. C语言的math相关的函数
  5. HNUCM-1435 最大最小值(分治法)
  6. SJIS_DBC_TO_SBC小例子
  7. PDFcrack暴力破解pdf密码
  8. 前后端分离前端框架的主要内容是什么?
  9. 面试经历记录——东方海外OOCL上海软件开发中心实习生
  10. 后端使用SpringBoot和Jwt工具与Redis数据库+前端Vue Element Admin实现用户携带token的登录功能案例
  11. 系统自带的最便捷的远程控制方法
  12. 服务器托管显示ping命令,用PING命令Ping通网络摄像机显示的数据是什么意思
  13. 【简单数学】【NOIP 20008】笨小猴
  14. UVA1626 简单DP
  15. php公众号交友源码_个性定制微信导航源码,PHP公众号导航源码,含手机wap版,微信数据...
  16. hexo(sakura)——标签、分类页面美化
  17. linux UPS状态,LINUX 与 UPS(转)
  18. 【vmware】虚拟机 mac 扩容
  19. 让树莓派开机运行Python脚本的简单方法
  20. 23. 尚融宝会员分页列表、锁定/解锁、用户登录日志

热门文章

  1. 【面试】嵌入式C语言题目整理
  2. leetcode-分数加减法
  3. OpenStack官方认证(COA)正式回归!
  4. Go unkown reversion问题解决
  5. kettle Oracle任务输入报错ora22924,ora01555
  6. 简单的android游戏框架——zgf
  7. 网易云课堂Linux运维在线班英文单词笔记
  8. 什么是API? [如何编写和阅读API文档]
  9. 中国互联网+化妆品行业深度调研及投资机会分析报告
  10. 比赛比分html模板,HTML5 球赛比分牌