知识大全 备忘录模式(Memento Pattern)

Posted 状态

篇首语:我认为人生最美好的主旨和人类生活最幸福的结果,无过于学习了。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 备忘录模式(Memento Pattern)相关的知识,希望对你有一定的参考价值。

备忘录模式(Memento Pattern)  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!

   描述     对象的状态可以定义为在特定的时间点对象的属性值 备忘录模式(Memento Pattern)应用于保存和跟踪对象的状态 以便于必要的时候可以把对象恢复到以前的状态 它很像恢复操作 备忘录模式(Memento Pattern)可以在不暴露对象的内部结构的情况下完成这样的功能 需要获取以前状态的对象就是指发起者(Originator) 当客户需要保存发起者的状态时 客户需要发起者的当前状态 发起者存贮所有保持它状态的属性到一个独立的对象 这个对象就是备忘录(纪念 记忆)Memento 把备忘录(Memento)对象返回给客户 备忘录(Memento)对象可以看作在给定的时间点包含另一个对象内部状态的对象 备忘录(Memento)对象必须向除了发起者以外的所有对象隐藏发起者变量的值 当发起者允许备忘录(Memento)对象访问它的内部状态时 备忘录(Memento)对象应该被设计为对其他对象采取访问限制的对象     当客户需要把发起者的状态恢复到以前的状态时 它只是简单的把备忘录(Memento)对象返回给发起者 发起者使用包含在备忘录(Memento)对象中的状态信息 恢复自己到备忘录(Memento)对象中保存的状态      例子     数据转化(Data conversion)总是那些涉及到从遗留系统转化到应用新技术的系统不可缺少的一部分 让我们假定一个需要把客户数据从文本文件移植到关系型数据库中的类似应用程序 在将客户数据发送给数据库以前 要对客户纪录进行验证     现实中 客户纪录需要包括很多属性 但是为了简单 让我们假定每一个客户纪录只有三个属性??first name last name和credit card number 验证过程也很简单 只要last name不为空而且credit card number(信用卡号)仅有 的数字组成 当发现一个无效的客户记录时 验证过程需要停止 提示用户修正数据并重新开始 在这个时间点上 数据转化(Data conversion)过程的状态需要保存在一个备忘录(Memento)对象内部 当用户重新开始验证过程时 数据装化过程从保存在备忘录(Memento)对象中的状态开始 验证过程从它停止的地方恢复 而不是从原数据起点重新开始 通常 备忘录(Memento)对象既可以保存在内存中也可以保存在持久介质上 在这个应用中 当应用被打断以后 状态需要保存 而且当应用再次运行的时候需要恢复 因此 在这种情况下 不适于把备忘录(Memento)对象保存在内存中 而是需要保存在持久介质上     不是直接把合法的客户纪录插入到关系数据库中 应用程序而是生成一个由SQL插入语句组成的文本文件 执行这些SQL语句可以把数据插入到数据库中     让我们为这个验证过程设计不同的组件      DataConverter(发起者)    DataConverter类(图 和Listing )是数据转化过程的实现    >  Listing : DataConverter Class    public class DataConverter   public static final String DATA_FILE = Data txt ;  public static final String OUTPUT_FILE = SQL txt ;  private long ID = ;  public Memento createMemento()   return (new Memento(ID));    public void setMemento(Memento memento)   if (memento != null)  ID = memento getID();    public long getLastProcessedID()   return ID;    public void setLastProcessedID(long lastID)   ID = lastID;    public boolean process()   boolean success = true;  String inputLine = ;  long currID = ;  try   File inFile = new File(DATA_FILE);  BufferedReader br = new BufferedReader(  new InputStreamReader(  new FileInputStream(inFile)));  long lastID = getLastProcessedID();  while ((inputLine = br readLine()) != null)   StringTokenizer st =  new StringTokenizer(inputLine );  String strID = st nextToken();  currID = new Long(strID) longValue();  if (lastID < currID)   Customer c =  new Customer(strID st nextToken()   st nextToken() st nextToken());  if (!(c isValid()))   success = false;  break;    ID = new Long(strID) longValue();  FileUtil util = new FileUtil();  util writeToFile(OUTPUT_FILE c getSQL()   true true);      br close();  //Try  catch (Exception ex)   System out println( An error has occurred +  ex getMessage());  System exit( );    if (success == false)   System out println( An error has occurred at ID= +  currID);  System out println( Data Record= + inputLine);  return false;    return true;    class Memento implements java io Serializable   private long lastProcessedID;  private Memento(long ID)   lastProcessedID = ID;    private long getID()   return lastProcessedID;    //end of class  //end of class    ID    实例变量ID组成了DataConverter的状态 它代表了最后一个被成功处理的客户纪录的客户ID      Memento    Memento定义为DataConverter的一个内部类 Memento将它的构造函数和其他方法定义为私有     在Java中 一个类可以访问它内部类的私有成员     DataConverter可以访问这些方法 但是其他的对象不可以访问 因为 当应用结束的时候 DataConverter的状态需要被保存 Memento对象需要被序列化(serialize)到一个文件中 因此 Memento类需要实现java io Serializable接口 以表明自己是一个可序列化(Serializable)的类     在JAVA中 一个序列化的类必须     使用transient 关键字明确指出不需要序列化的属性   实现java io Serializable接口  可以访问它的第一个非序列化夫类的零参数的构造函数      process    process方法读取元数据文件 通过Customer helper类验证客户数据 对于每一个有效的客户纪录 相应的SQL插入语句被写入到输出文件中 当遇到无效客户纪录时 数据转化过程停止      createMemento    如方法名字 这个方法负责创建Memento对象 它把DataConverter对象的当前状态保存到一个Memento实例内 并放回它      setMemento    取出输入的Memento对象的状态信息 重新设置DataConverter的状态到此状态      DCClient (Client)    客户DCClient(Listing )首先初始化DataConverter 调用DataConverter实例的process方法开始数据转化过程 如果process方法在处理原数据文件期间遇到无效的客户数据 它会调用DataConverter实例的createMemento方法捕获当前状态 createMemento方法返回一个Memento对象 客户DCClient使用MementoHandler对象负责序列化Memento实例到一个文件     Listing : DCClient Class    public class DCClient   public static void main(String[] args)   MementoHandler objMementoHandler = new MementoHandler();  DataConverter objConverter = new DataConverter();  objConverter setMemento(objMementoHandler getMemento());  if (!(objConverter process()))   System out println( Description: Invalid data +   Process Stopped );  System out println( Please correct the Data and +   Run the Application Again );  objMementoHandler setMemento(  objConverter createMemento());          一旦数据被校正 客户DCClient就会再次运行     客户DCClient调用MementoHandler 上的getMemento 方法请求它保存Memento对象   MementoHandler 从文件中反序列化以前的Memento对象 并把它放回给客户   客户把它作为DataConverter 的set Memento方法的参数传递给DataConverter DataConverter使自己返回到保存在Memento对象中的状态 从原来停止的地方恢复数据转化过程     MementoHandler    The MementoHandler (Listing ) 包含了Memento 对象的一个引用 客户DCClient把一个Memento的实例传递给它     Listing : MementoHandler Class    public class MementoHandler   public static final String ID_FILE = ID txt ;  private DataConverter Memento objMemento = null;  public DataConverter Memento getMemento()   ObjectInputStream objStream = null;  FileUtil util = new FileUtil();  if (util isFileExists(ID_FILE))   //read the object from the file  try   objStream = new ObjectInputStream(  new FileInputStream(new File(ID_FILE)));  objMemento = (DataConverter Memento)  objStream readObject();  objStream close();   catch (Exception e)   System out println( Error Reading Memento );  System exit( );    //delete the old memento  util deleteFile(ID_FILE);    return objMemento;    public void setMemento(DataConverter Memento memento)   ObjectOutputStream objStream = null;  //write the object to the file  try   objStream = new ObjectOutputStream(  new FileOutputStream(new File(ID_FILE)));  objStream writeObject(memento);  objStream close();   catch (Exception e)   System out println( Error Writing Memento );  System exit( );      //end of class    如上面介绍的 任何时候数据转化过程没有验证完全部的原数据文件 客户要捕获DataConverter的状态到一个Memento中 并停止应用程序 为了使这个Memento在下次运行的时候有效 它必须被保存到持久介质上 这就涉及到了对象的序列化 如果在下次运行的时候 DataConverter要返回到它原来的状态 这个Memento对象必须被重构 这又涉及到了对象的反序列化 这些细节由MementoHandler类来处理 使得所有客户(DataConverter和Memento对象)免于处理这些细节     这样也是的改变Memento的存储方式变得很容易 例如 Memento需要保存到数据库中 而不是文件中时 只要修改MementoHandler就可以了 不需要修改任何客户类的实现     图 显示了在数据转化这个例子中 不同对象之间的关联关系    >  Figure shows the application message flow    >  例子 (自己找的)    经常使用计算机的人恐怕对系统备份(Memento)不会陌生 当你的Windows系统运行正常时 对它进行备份 当系统运行有问题时 就可以调用备份快速的将系统恢复 这样就可以大量节省重新装系统的痛苦 特别是当你缺少某一驱动 或在装系统是出现一些怪问题时 犹为痛苦 我想有过这种经历的人应该很了解吧 呵呵!    好了 下面让我们看看这个过程该如何实现吧      我们先定义Windows系统(WindowsSystem)类     public class WindowsSystem   private String state;  public Memento createMemento()  //创建备份 保存当前状态  return new Memento(state);    public void restoreMemento(Memento memento) //从备份中恢复系统  this state=memento getState();    public String getState() //获得状态  return this state;    public void setState(String state) //设置状态  this state=state;  System out println(当前系统处于+this state);         再定义备份(Memento)类     public class Memento   private String state;  public Memento(String state)  //备份  this state=state;    public String getState() //获得状态  return this state;    public void setState(String state) //设置状态  this state=state;         定义用户(User)类     public class User   private Memento memento;  public Memento retrieveMemento()  //恢复系统  return mento;    public void saveMemento(Memento memento) //保存系统  mento=memento;         编写测试类     public class Test   public static void main(String args[])   WindowsSystem Winxp = new WindowsSystem(); //Winxp系统  User user = new User();  //某一用户  Winxp setState(好的状态);  //Winxp处于好的运行状态  user saveMemento(Winxp createMemento()); //用户对系统进行备份 Winxp系统要产生备份文件  Winxp setState(坏的状态);  //Winxp处于不好的运行状态  Winxp restoreMemento(user retrieveMemento());  //用户发恢复命令 系统进行恢复  System out println(当前系统处于+Winxp getState());         说明     A 定义 Memento对象是一个保存另外一个对象内部状态拷贝的对象 这样以后就可以将该对象恢复到原先保存的状态     B Memento模式的用意是在不破坏封装的条件下 将一个对象的状态捕捉住 并外部化 存储起来 从而可以在将来合适的时候把这个对象还原到存储起来的状态     C Memento模式所涉及的角色有三个 备忘录角色 发起人角色和负责人角色      备忘录角色的作用     ( )    将发起人对象的内部状态存储起来 备忘录可以根据发起人对象的判断来决定存储多少发起人对象的内部状态     ( )    备忘录可以保护其内容不被发起人对象之外的任何对象所读取      发起人角色的作用     ( )    创建一个含有当前内部状态的备忘录对象     ( )    使用备忘录对象存储其内部状态      负责人角色的作用     ( )    负责保存备忘录对象     ( )    不检查备忘录对象的内容     D 在本例中 备份(Memento)类是备忘录角色 Windows系统(WindowsSystem)类是发起人角色 用户(User)类是负责人角色 cha138/Article/program/Java/gj/201311/27656

相关参考

知识大全 教程:适配器模式(Adapter Pattern)组图

教程:适配器模式(AdapterPattern)组图  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!

知识大全 外观设计模式组图(Fa?ade pattern)

外观设计模式组图(Fa?adepattern)  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  描

知识大全 深入浅出Java设计之备忘录模式

深入浅出Java设计之备忘录模式  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  一引子  俗话说

知识大全 正则表达式使用代码片段

  在javautilregex包中包括了两个类Pattern(模式类)和Matcher(匹配器类)Pattern类是用来表达和陈述所要搜索模式的对象Matcher类是真正影响搜索的对象另加一个新的例

知识大全 技术解析:什么是模式

  现在软件设计里到处都是模式框架有次朋友问什么是模式?我也在学习中就我的学习经验给出以下小结(注意个人观点仅供参考欢迎指正)    .什么是模式?    模式即pattern其实就是解决某一类问题的

知识大全 初学C#+ASP.NET+Oracle备忘录

初学C#+ASP.NET+Oracle备忘录  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  在中

公司内部常用的书面交流形式是

公司内部常用的书面交流形式是_____。A、备忘录B、信件C、报告D、请示答案:A解析:备忘录是一种公司内部常用的书面交流方式,常用于提醒会议日程、任务目标等重要事宜。通常情况下,与信件相比,备忘录较

视野:节令备忘

元旦至少有3000年历史“元旦”一词最早出现于《晋书》:“颛帝以孟夏正月为元,其实正朔元旦之春。”颛顼是“三皇五帝”之一,如果这个记载属实,那么元旦至少已有3000多年的历史了。我国古代过元旦,历朝历

知识大全 在Eclipse中构建备忘单

开源技术:在Eclipse中构建备忘单  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  Eclip

知识大全 入门基础-Oracle常用脚本备忘

入门基础-Oracle常用脚本备忘  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!创建一个表T使之具