热门标签 | HotTags
当前位置:  开发笔记 > 运维 > 正文

详解备忘录模式及其在Java设计模式编程中的实现

这篇文章主要介绍了详解备忘录模式及其在Java设计模式编程中的实现,备忘录模式数据的存储过程中应当注意浅拷贝和深拷贝的问题,需要的朋友可以参考下

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

2. 使用的原因
想要恢复对象某时的原有状态。

3. 适用的情况举例
有很多备忘录模式的应用,只是我们已经见过,却没细想这是备忘录模式的使用罢了,略略举几例:
eg1. 备忘录在jsp+javabean的使用:
在一系统中新增帐户时,在表单中需要填写用户名、密码、联系电话、地址等信息,如果有些字段没有填写或填写错误,当用户点击“提交”按钮时,需要在新增页面上保存用户输入的选项,并提示出错的选项。这就是利用JavaBean的scope="request"或scope="session"特性实现的,即是用备忘录模式实现的。
eg2. 修理汽车的刹车时。首先移开两边的挡板,露出左右刹车片。只能卸下一片,这时另一片作为一个备忘录来表明刹车是怎样安装的。在这片修理完成后,才可以卸下另一片。当第二片卸下时,第一片就成了备忘录。
eg3. 都说人生没有后悔药可买,我们都在为所做的事付出着代价,但在软世界里却有“后悔药”,我改变了某东西的某些状态之后,只要我们之前保存了该东西的某状态,我们就可以通过备忘录模式实现该东西的状态还原,其实这何尝不是一个能使时光倒流的“月光宝盒”,总“神奇”一词了得。

4. 类图结构及说明
(1)类图如下所示:

201642993348501.jpg (466×148)

(2)类说明           
(i)Memento:备忘录角色,  主要负责的工作如下:
将发起人对象的内部状态存储起来;
可以保护其内容不被发起人(Originator)对象之外的任何对象所读取。
(ii)Originator:发起人角色,主要完成如下工作:
创建一个含有当前的内部状态的备忘录对象;
使用备忘录对象存储其内部状态。
(iii)Caretaker:负责人角色,完成工作如下:
负责保存备忘录对象;
不保存备忘录对象的内容。      

5.实例

/** 
 * 数据对象 
 */ 
public class DataState { 
  private String action; 
 
  public void setAction(String action) { 
    this.action = action; 
  } 
   
  public String getAction() { 
    return action; 
  } 
 
} 
/** 
 * 一个保存另外一个对象内部状态拷贝 的对象.这样以后就可以将该对象恢复到原先保存的状态. 
 */ 
import java.io.File; 
import java.io.Serializable; 
 
public class Memento implements Serializable { 
 
  /*private int number; 
  private File file = null; 
 
  public Memento(Originator o) { 
    this.number = o.getNumber(); 
    this.file = o.getFile(); 
  } 
 
  public int getNumber() { 
    return this.number; 
  } 
 
  public void setNumber(int number) { 
    this.number = number; 
  } 
 
  public File getFile() { 
    return this.file; 
  } 
 
  public void setFile(File file) { 
    this.file = file; 
  } 
*/ 
  private DataState state; 
  public Memento(Originator o) { 
    this.state = o.getState(); 
  } 
   
  public DataState getState() { 
    return state; 
  } 
   
  public void setState(DataState state) { 
    this.state = state; 
  } 
} 

public class Originator { 
 
/* private int number; 
  private File file = null; 
 
  public Originator() { 
 
  } 
 
  // 创建一个Memento,将自身作为参数传入 
  public Memento getMemento() { 
    return new Memento(this); 
  } 
 
  // 从Memento中取出保存的数据,恢复为原始状态 
  public void setMemento(Memento m) { 
    number = m.getNumber(); 
    file = m.getFile(); 
  } 
 
  public int getNumber() { 
    return number; 
  } 
 
  public void setNumber(int number) { 
    this.number = number; 
  } 
 
  public File getFile() { 
    return file; 
  } 
 
  public void setFile(File file) { 
    this.file = file; 
  }*/ 
   
  private DataState state; 
  public Originator() { 
     
  } 
   
  public Originator(DataState state) { 
    this.state = state; 
  } 
   
  // 创建一个Memento,将自身作为参数传入 
  public Memento getMemento() { 
    return new Memento(this); 
  } 
   
  // 从Memento中取出保存的数据,恢复为原始状态 
  public void setMemento(Memento m) { 
    /* 
     * getMemento() 创建的对象,保存在某个容器里, 
     * 当需要恢复时,将其传入当前方法, 再使用getState(),得出 
     */ 
    this.state = m.getState(); 
  } 
   
  public DataState getState() { 
    return state; 
  } 
   
  public void setState(DataState state) { 
    this.state = state; 
  } 
} 

/* 
 * Originator用于 加载数据, 建立Memento对象,及通过Memento恢复原始数据 
 */ 
public class Test { 
  public static void main(String[] args) { 
     
//   Originator originator = new Originator(); 
//   originator.setNumber(8); 
//    
//   Memento memento = originator.getMemento(); 
//   System.out.println(memento.getNumber()); 
     
    DataState state = new DataState(); 
    state.setAction("copy a character"); 
    Originator originator = new Originator(); 
    System.out.println("创建原始数据"); 
    originator.setState(state); 
     
    System.out.println("创建备忘录对象, 保存原始数据状态"); 
    Memento memento = originator.getMemento(); 
     
    System.out.println("创建了一个新数据"); 
    originator.setState(new DataState()); 
 
    System.out.println("创建新数据后:" + originator.getState().getAction()); 
     
    /* 
     * memento 需要保存在某地,需要时取出,以恢复它内部所保存的数据 
     */ 
    System.out.println("创建新数据后,恢复原数据"); 
    originator.setMemento(memento); 
    System.out.println(originator.getState().getAction()); 
  } 
} 

打印:

创建原始数据 
创建备忘录对象, 保存原始数据状态 
创建了一个新数据 
创建新数据后:null 
创建新数据后,恢复原数据 
copy a character 


推荐阅读
  • 春季职场跃迁指南:如何高效利用金三银四跳槽季
    随着每年的‘金三银四’跳槽高峰期的到来,许多职场人士都开始考虑是否应该寻找新的职业机会。本文将探讨如何制定有效的职业规划、撰写吸引人的简历以及掌握面试技巧,助您在这关键时期成功实现职场跃迁。 ... [详细]
  • 本文探讨了如何在Docker构建过程中使用动态环境变量,特别是针对Docker v1.9及以上版本的用户。我们将介绍如何声明和使用构建参数,以及这些参数对构建缓存的影响。 ... [详细]
  • 2017年软件开发领域的七大变革
    随着技术的不断进步,2017年对软件开发人员而言将充满挑战与机遇。本文探讨了开发人员需要适应的七个关键变化,包括人工智能、聊天机器人、容器技术、应用程序版本控制、云测试环境、大众开发者崛起以及系统管理的云迁移。 ... [详细]
  • 本文详细介绍如何在华为鲲鹏平台上构建和使用适配ARM架构的Redis Docker镜像,解决常见错误并提供优化建议。 ... [详细]
  • Flutter 核心技术与混合开发模式深入解析
    本文深入探讨了 Flutter 的核心技术,特别是其混合开发模式,包括统一管理模式和三端分离模式,以及混合栈原理。通过对比不同模式的优缺点,帮助开发者选择最适合项目的混合开发策略。 ... [详细]
  • 使用Echarts for Weixin 小程序实现中国地图及区域点击事件
    本文介绍了如何使用Echarts for Weixin在微信小程序中构建中国地图,并实现区域点击事件。包括效果展示、条件准备和逻辑实现的具体步骤。 ... [详细]
  • 将字符串中的嵌套列表转换回嵌套列表 ... [详细]
  • 本文将探讨如何在 Struts2 中使用 ActionContext 和 ServletActionContext 来获取请求参数和会话信息,同时解释它们的内部机制和最佳实践。 ... [详细]
  • RTThread线程间通信
    线程中通信在裸机编程中,经常会使用全局变量进行功能间的通信,如某些功能可能由于一些操作而改变全局变量的值,另一个功能对此全局变量进行读取& ... [详细]
  • 本文介绍了存储器的基本原理及其分类,包括不同类型的存储介质和存储方式,并详细解释了各种存储器的特点和应用场景。 ... [详细]
  • 本文总结了近年来在实际项目中使用消息中间件的经验和常见问题,旨在为Java初学者和中级开发者提供实用的参考。文章详细介绍了消息中间件在分布式系统中的作用,以及如何通过消息中间件实现高可用性和可扩展性。 ... [详细]
  • DirectShow Filter 开发指南
    本文总结了 DirectShow Filter 的开发经验,重点介绍了 Source Filter、In-Place Transform Filter 和 Render Filter 的实现方法。通过使用 DirectShow 提供的类,可以简化 Filter 的开发过程。 ... [详细]
  • 如何在DedeCMS专题页节点文档中调用自定义模型字段?
    在完成DedeCMS专题页节点文章列表样式的修改后,如果需要在列表中显示自定义模型的字段,由于DedeCMS默认不支持这一功能,因此需要进行一些二次开发。本文将详细介绍如何通过修改模板文件和核心文件来实现这一需求。 ... [详细]
  • 本文详细介绍了CSS中元素的显示模式,包括块元素、行内元素和行内块元素的特性和应用场景。 ... [详细]
  • 本文介绍了如何将Spring属性占位符与Jersey的@Path和@ApplicationPath注解结合使用,以便在资源路径中动态解析属性值。 ... [详细]
author-avatar
mobiledu2502880051
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有