备忘录模式(Memento Pattern).doc_第1页
备忘录模式(Memento Pattern).doc_第2页
备忘录模式(Memento Pattern).doc_第3页
备忘录模式(Memento Pattern).doc_第4页
备忘录模式(Memento Pattern).doc_第5页
已阅读5页,还剩4页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

描述:对象的状态可以定义为在特定的时间点对象的属性值。备忘录模式(MementoPattern)应用于保存和跟踪对象的状态,以便于必要的时候可以把对象恢复到以前的状态。它很像恢复操作。备忘录模式(MementoPattern)可以在不暴露对象的内部结构的情况下完成这样的功能。需要获取以前状态的对象就是指发起者(Originator)。当客户需要保存发起者的状态时,客户需要发起者的当前状态。发起者存贮所有保持它状态的属性到一个独立的对象,这个对象就是备忘录(纪念、记忆)Memento,把备忘录(Memento)对象返回给客户。备忘录(Memento)对象可以看作在给定的时间点包含另一个对象内部状态的对象。备忘录(Memento)对象必须向除了发起者以外的所有对象隐藏发起者变量的值。当发起者允许备忘录(Memento)对象访问它的内部状态时,备忘录(Memento)对象应该被设计为对其他对象采取访问限制的对象。当客户需要把发起者的状态恢复到以前的状态时,它只是简单的把备忘录(Memento)对象返回给发起者。发起者使用包含在备忘录(Memento)对象中的状态信息,恢复自己到备忘录(Memento)对象中保存的状态。例子:数据转化(Dataconversion)总是那些涉及到从遗留系统转化到应用新技术的系统不可缺少的一部分。让我们假定一个需要把客户数据从文本文件移植到关系型数据库中的类似应用程序。在将客户数据发送给数据库以前,要对客户纪录进行验证。现实中,客户纪录需要包括很多属性,但是为了简单,让我们假定每一个客户纪录只有三个属性?firstname、lastname和creditcardnumber。验证过程也很简单,只要lastname不为空而且creditcardnumber(信用卡号)仅有0-9的数字组成。当发现一个无效的客户记录时,验证过程需要停止、提示用户修正数据并重新开始。在这个时间点上,数据转化(Dataconversion)过程的状态需要保存在一个备忘录(Memento)对象内部。当用户重新开始验证过程时,数据装化过程从保存在备忘录(Memento)对象中的状态开始,验证过程从它停止的地方恢复,而不是从原数据起点重新开始。通常,备忘录(Memento)对象既可以保存在内存中也可以保存在持久介质上。在这个应用中,当应用被打断以后,状态需要保存,而且当应用再次运行的时候需要恢复。因此,在这种情况下,不适于把备忘录(Memento)对象保存在内存中,而是需要保存在持久介质上。不是直接把合法的客户纪录插入到关系数据库中,应用程序而是生成一个由SQL插入语句组成的文本文件,执行这些SQL语句可以把数据插入到数据库中。让我们为这个验证过程设计不同的组件。DataConverter(发起者)DataConverter类(图32.1和Listing32.1)是数据转化过程的实现。Figure32.1:DataConverterClass?TheOriginatorListing32.1:DataConverterClass1. publicclassDataConverter 2. publicstaticfinalStringDATA_FILE=Data.txt; 3. publicstaticfinalStringOUTPUT_FILE=SQL.txt; 4. privatelongID=0; 5. publicMementocreateMemento() 6. return(newMemento(ID); 7. 8. publicvoidsetMemento(Mementomemento) 9. if(memento!=null) 10. ID=memento.getID(); 11. 12. publiclonggetLastProcessedID() 13. returnID; 14. 15. publicvoidsetLastProcessedID(longlastID) 16. ID=lastID; 17. 18. publicbooleanprocess() 19. booleansuccess=true; 20. StringinputLine=; 21. longcurrID=0; 22. try 23. FileinFile=newFile(DATA_FILE); 24. BufferedReaderbr=newBufferedReader( 25. newInputStreamReader( 26. newFileInputStream(inFile); 27. longlastID=getLastProcessedID(); 28. while(inputLine=br.readLine()!=null) 29. StringTokenizerst= 30. newStringTokenizer(inputLine,); 31. StringstrID=st.nextToken(); 32. currID=newLong(strID).longValue(); 33. if(lastIDcurrID) 34. Customerc= 35. newCustomer(strID,st.nextToken(), 36. st.nextToken(),st.nextToken(); 37. if(!(c.isValid() 38. success=false; 39. break; 40. 41. ID=newLong(strID).longValue(); 42. FileUtilutil=newFileUtil(); 43. util.writeToFile(OUTPUT_FILE,c.getSQL(), 44. true,true); 45. 46. 47. br.close(); 48. /Try 49. catch(Exceptionex) 50. System.out.println(Anerrorhasoccurred+ 51. ex.getMessage(); 52. System.exit(1); 53. 54. if(success=false) 55. System.out.println(AnerrorhasoccurredatID=+ 56. currID); 57. System.out.println(DataRecord=+inputLine); 58. returnfalse; 59. 60. returntrue; 61. 62. classMementoimplementsjava.io.Serializable 63. privatelonglastProcessedID; 64. privateMemento(longID) 65. lastProcessedID=ID; 66. 67. privatelonggetID() 68. returnlastProcessedID; 69. 70. /endofclass 71. /endofclass ID实例变量ID组成了DataConverter的状态,它代表了最后一个被成功处理的客户纪录的客户ID。MementoMemento定义为DataConverter的一个内部类,Memento将它的构造函数和其他方法定义为私有。在Java中,一个类可以访问它内部类的私有成员。DataConverter可以访问这些方法,但是其他的对象不可以访问。因为,当应用结束的时候,DataConverter的状态需要被保存。Memento对象需要被序列化(serialize)到一个文件中。因此,Memento类需要实现java.io.Serializable接口,以表明自己是一个可序列化(Serializable)的类。在JAVA中,一个序列化的类必须:使用transient关键字明确指出不需要序列化的属性。实现java.io.Serializable接口可以访问它的第一个非序列化夫类的零参数的构造函数。processprocess方法读取元数据文件,通过Customerhelper类验证客户数据。对于每一个有效的客户纪录,相应的SQL插入语句被写入到输出文件中。当遇到无效客户纪录时,数据转化过程停止。createMemento如方法名字,这个方法负责创建Memento对象,它把DataConverter对象的当前状态保存到一个Memento实例内,并放回它。setMemento取出输入的Memento对象的状态信息,重新设置DataConverter的状态到此状态。DCClient(Client)客户DCClient(Listing32.2)首先初始化DataConverter,调用DataConverter实例的process方法开始数据转化过程。如果process方法在处理原数据文件期间遇到无效的客户数据,它会调用DataConverter实例的createMemento方法捕获当前状态。createMemento方法返回一个Memento对象。客户DCClient使用MementoHandler对象负责序列化Memento实例到一个文件。Listing32.2:DCClientClass1. publicclassDCClient 2. publicstaticvoidmain(Stringargs) 3. MementoHandlerobjMementoHandler=newMementoHandler(); 4. DataConverterobjConverter=newDataConverter(); 5. objConverter.setMemento(objMementoHandler.getMemento(); 6. if(!(objCcess() 7. System.out.println(Description:Invaliddata-+ 8. ProcessStopped); 9. System.out.println(PleasecorrecttheDataand+ 10. RuntheApplicationAgain); 11. objMementoHandler.setMemento( 12. objConverter.createMemento(); 13. 14. 15. 一旦数据被校正,客户DCClient就会再次运行。客户DCClient调用MementoHandler上的getMemento方法请求它保存Memento对象。MementoHandler从文件中反序列化以前的Memento对象,并把它放回给客户。客户把它作为DataConverter的set-Memento方法的参数传递给DataConverter。DataConverter使自己返回到保存在Memento对象中的状态。从原来停止的地方恢复数据转化过程。MementoHandlerTheMementoHandler(Listing32.3)包含了Memento对象的一个引用。客户DCClient把一个Memento的实例传递给它。Listing32.3:MementoHandlerClass1. publicclassMementoHandler 2. publicstaticfinalStringID_FILE=ID.txt; 3. privateDataConverter.MementoobjMemento=null; 4. publicDataConverter.MementogetMemento() 5. ObjectInputStreamobjStream=null; 6. FileUtilutil=newFileUtil(); 7. if(util.isFileExists(ID_FILE) 8. /readtheobjectfromthefile 9. try 10. objStream=newObjectInputStream( 11. newFileInputStream(newFile(ID_FILE); 12. objMemento=(DataConverter.Memento) 13. objStream.readObject(); 14. objStream.close(); 15. catch(Exceptione) 16. System.out.println(ErrorReadingMemento); 17. System.exit(1); 18. 19. /deletetheoldmemento 20. util.deleteFile(ID_FILE); 21. 22. returnobjMemento; 23. 24. publicvoidsetMemento(DataConverter.Mementomemento) 25. ObjectOutputStreamobjStream=null; 26. /writetheobjecttothefile 27. try 28. objStream=newObjectOutputStream( 29. newFileOutputStream(newFile(ID_FILE); 30. objStream.writeObject(memento); 31. objStream.close(); 32. catch(Exceptione) 33. System.out.println(ErrorWritingMemento); 34. System.exit(1); 35. 36. 37. /endofclass 如上面介绍的,任何时候数据转化过程没有验证完全部的原数据文件,客户要捕获DataConverter的状态到一个Memento中,并停止应用程序。为了使这个Memento在下次运行的时候有效,它必须被保存到持久介质上,这就涉及到了对象的序列化。如果在下次运行的时候,DataConverter要返回到它原来的状态,这个Memento对象必须被重构,这又涉及到了对象的反序列化。这些细节由MementoHandler类来处理,使得所有客户(DataConverter和Memento对象)免于处理这些细节。这样也是的改变Memento的存储方式变得很容易。例如,Memento需要保存到数据库中,而不是文件中时,只要修改MementoHandler就可以了,不需要修改任何客户类的实现。图32.2显示了在数据转化这个例子中,不同对象之间的关联关系。Figure32.2:DataConversionApplication?ClassAssociationFigure32.3showstheapplicationmessageflow.Figure32.3:ApplicationMessageFlow例子2(自己找的)经常使用计算机的人恐怕对系统备份(Memento)不会陌生,当你的Windows系统运行正常时,对它进行备份,当系统运行有问题时,就可以调用备份快速的将系统恢复,这样就可以大量节省重新装系统的痛苦,特别是当你缺少某一驱动,或在装系统是出现一些怪问题时,犹为痛苦。我想有过这种经历的人应该很了解吧,呵呵!好了,下面让我们看看这个过程该如何实现吧:1、我们先定义Windows系统(WindowsSystem)类:1. publicclassWindowsSystem 2. privateStringstate; 3. publicMementocreateMemento()/创建备份,保存当前状态 4. returnnewMemento(state); 5. 6. publicvoidrestoreMemento(Mementomemento)/从备份中恢复系统 7. this.state=memento.getState(); 8. 9. publicStringgetState()/获得状态 10. returnthis.state; 11. 12. publicvoidsetState(Stringstate)/设置状态 13. this.state=state; 14. System.out.println(当前系统处于+this.state); 15. 16. 2、再定义备份(Memento)类:1. publicclassMemento 2. privateStringstate; 3. publicMemento(Stringstate)/备份 4. this.state=state; 5. 6. publicStringgetState()/获得状态 7. returnthis.state; 8. 9. publicvoidsetState(Stringstate)/设置状态 10. this.state=state; 11. 12. 3、定义用户(User)类:1. publicclassUser 2. privateMementomemento; 3. publicMementoretrieveMemento()/恢复系统 4. returnthis.memento; 5. 6. publicvoidsaveMemento(Mementomemento)/保存系统 7. this.memento=memento; 8. 9. 4、编写测试类:1. publicclassTest

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论