设计模式-原型模式.ppt_第1页
设计模式-原型模式.ppt_第2页
设计模式-原型模式.ppt_第3页
设计模式-原型模式.ppt_第4页
设计模式-原型模式.ppt_第5页
已阅读5页,还剩22页未读 继续免费阅读

下载本文档

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

文档简介

设计模式 原型 Prototype 模式 Session3By佘丹 1stJul2008 原型 Prototype 模式 通过给出一个原型对象来指明所要创建的对象类型 然后用拷贝这个原型对象的办法创建出更多的同类型对象 孙大圣的毫毛孙悟空在与黄风怪的战斗中 使一个身外身的手段 把毫毛揪下一把 用口嚼得粉碎 望上一喷 叫声 变 变有百十个行者 都是一样得打扮 各执一根铁棒 把那怪围在空中 换而言之 孙悟空可以根据自己的形象 拷贝出很多 身外身 来 孙悟空这种身外身的手段在面向对象设计领域里叫原型 Prototype 模式 1 Java对原型模式的支持 在Java里面 我们可以通过Clone 方法实现原型模式 任何类 只要想支持克隆 必须实现Cloneable接口 Cloneable接口中有Clone方法 可以在类中复写实现自定义的克隆方法 克隆的实现方法有三种 浅拷贝 深拷贝和完全拷贝 1 浅拷贝被拷贝对象的所有变量都含有与原来的对象相同的值 而所有的对其他对象的引用仍然指向原来的对象 换言之 浅拷贝仅仅拷贝所考虑的对象 而不拷贝它所引用的对象 2 深拷贝被拷贝对象的所有变量都含有与原来的对象相同的值 除去那些引用其他对象的变量 那些引用其他对象的变量将指向被拷贝过的新对象 而不再是原有的那些被引用的对象 换言之 深拷贝把要拷贝的对象所引用的对象都拷贝了一遍 3 完全拷贝完全拷贝不仅把要拷贝的对象所直接引用的对象都拷贝了一遍 还把该对象间接引用到的所有对象也都拷贝了一遍 这是最彻底的一种拷贝 2 Java的clone 方法 CloneprotectedObjectclone throwsCloneNotSupportedExceptionThismethodmaybecalledtocreateanewcopyoftheObject Thetypicalbehaviorisasfollows o o clone isfalseo getClass o clone getClass istrueo equals o istrueHowever thesearenotstrictrequirements andmaybeviolatedifnecessary Ofthethreerequirements thelastisthemostcommonlyviolated particularlyifthesubclassdoesnotoverrideequals Object 55 IftheObjectyoucallclone ondoesnotimplementCloneable whichisaplaceholderinterface thenaCloneNotSupportedExceptionisthrown NoticethatObjectdoesnotimplementCloneable thismethodexistsasaconvenienceforsubclassesthatdo Object simplementationofcloneallocatesspaceforthenewObjectusingthecorrectclass withoutcallinganyconstructors andthenfillsinallofthenewfieldvalueswiththeoldfieldvalues Thus itisashallowcopy However subclassesarepermittedtomakeadeepcopy AllarraytypesimplementCloneable andoverridethismethodasfollows itshouldneverfail publicObjectclone try super clone catch CloneNotSupportedExceptione thrownewInternalError e getMessage 2 Java的clone 方法 clone方法将对象复制了一份并返回给调用者 一般而言 clone 方法满足 对任何的对象x 都有x clone x克隆对象与原对象不是同一个对象 对任何的对象x 都有x clone getClass x getClass 克隆对象与原对象的类型一样 如果对象x的equals 方法定义恰当 那么x clone equals x 应该成立 Java中对象的克隆 为了获取对象的一份拷贝 我们可以利用Object类的clone 方法 在派生类中覆盖基类的clone 方法 并声明为public 在派生类的clone 方法中 调用super clone 在派生类中实现Cloneable接口 3 Java的类拷贝实现代码 classStudentimplementsCloneable Stringname intage Student Stringname intage this name name this age age publicObjectclone Objecto null try o Student super clone Object中的clone 识别出你要复制的是哪一个对象 catch CloneNotSupportedExceptione System out println e toString returno publicstaticvoidmain String args Students1 newStudent zhangsan 18 Students2 Student s1 clone s2 name lisi s2 age 20 System out println name s1 name age s1 age 修改学生2后 不影响学生1的值 为什么我们在派生类中覆盖Object的clone 方法时 一定要调用super clone 呢 在运行时刻 Object中的clone 识别出你要复制的是哪一个对象 然后为此对象分配空间 并进行对象的复制 将原始对象的内容一一复制到新对象的存储空间中 继承自java lang Object类的clone 方法是浅复制 后面的代码可以证明 浅拷贝 3 Java的类拷贝实现代码 classProfessor Stringname intage Professor Stringname intage this name name this age age classStudentimplementsCloneable Stringname 常量对象 intage Professorp 学生1和学生2的引用值都是一样的 Student Stringname intage Professorp this name name this age age this p p publicObjectclone Studento null try o Student super clone catch CloneNotSupportedExceptione System out println e toString o p Professor p clone returno publicstaticvoidmain String args Professorp newProfessor wanGWu 50 Students1 newStudent zhangsan 18 p Students2 Student s1 clone s2 p name lisi s2 p age 30 System out println name s1 p name age s1 p age 学生1的教授为lisi age为30 被改了 浅拷贝 3 Java的类拷贝实现代码 classProfessorimplementsCloneable Stringname intage Professor Stringname intage this name name this age age publicObjectclone Objecto null try o super clone catch CloneNotSupportedExceptione System out println e toString returno classStudentimplementsCloneable Stringname 常量对象 intage Professorp 学生1和学生2的引用值都是一样的 Student Stringname intage Professorp this name name this age age this p p publicObjectclone Studento null try o Student super clone catch CloneNotSupportedExceptione System out println e toString o p Professor p clone returno publicstaticvoidmain String args Professorp newProfessor wanGWu 50 Students1 newStudent zhangsan 18 p Students2 Student s1 clone s2 p name lisi s2 p age 30 System out println name s1 p name age s1 p age 学生1的教授不改变 深拷贝 3 Java的类拷贝实现代码 classProfessorimplementsSerializable Stringname intage Professor Stringname intage this name name this age age classStudentimplementsSerializable Stringname 常量对象 intage Professorp 学生1和学生2的引用值都是一样的 Student Stringname intage Professorp this name name this age age this p p publicObjectfullClone throwsIOException OptionalDataException ClassNotFoundException 将对象写到流里ByteArrayOutoutStreambo newByteArrayOutputStream ObjectOutputStreamoo newObjectOutputStream bo oo writeObject this 从流里读出来ByteArrayInputStreambi newByteArrayInputStream bo toByteArray ObjectInputStreamoi newObjectInputStream bi return oi readObject publicstaticvoidmain String args Professorp newProfessor wangwu 50 Students1 newStudent zhangsan 18 p Students2 Student s1 fullClone s2 p name lisi s2 p age 30 System out println name s1 p name age s1 p age 学生1的教授不改变 完全拷贝 在Java语言里深复制一个对象 常常可以先使对象实现Serializable接口 然后把对象 实际上只是对象的一个拷贝 写到一个流里 腌成干菜 再从流里读出来 把干菜回鲜 便可以重建对象 4 Prototype模式的结构 客户 Client 角色 客户类提出创建对象的请求 抽象原型 Prototype 角色 这是一个抽象角色 通常由一个接口类或抽象类实现 此角色给出所有的具体原型类所需的接口 在Java中 抽象原型角色通常实现了Cloneable接口 具体原型 ConcretePrototype 角色 被复制的对象 此角色需要实现抽象原型角色所要求的接口 4 1Prototype模式实现 抽象原型 publicabstractclassAbstractSpoonimplementsCloneable StringspoonName publicvoidsetSpoonName StringspoonName this spoonName spoonName publicStringgetSpoonName returnthis spoonName publicObjectclone Objectobject null try object super clone catch CloneNotSupportedExceptionexception System err println AbstractSpoonisnotCloneable returnobject 4 2Prototype模式实现 具体原型 publicclassSaladSpoonextendsAbstractSpoon publicSaladSpoon setSpoonName SaladSpoon publicclassSoupSpoonextendsAbstractSpoon publicSoupSpoon setSpoonName SoupSpoon 4 3Prototype模式实现 客户 publicclassClient paramargs publicstaticvoidmain String args AbstractSpoonspoon1 newSoupSpoon AbstractSpoonspoon2 AbstractSpoon spoon1 clone System out println spoon2 getSpoonName AbstractSpoonspoon3 newSaladSpoon AbstractSpoonspoon4 AbstractSpoon spoon3 clone System out println spoon4 getSpoonName 5 带原型管理器的原型模式 客户 Client 角色 客户端类向原型管理器提出创建对象的请求 抽象原型 Prototype 角色 这是一个抽象角色 通常由一个接口或抽象类实现 此角色给出所有的具体原型类所需的接口 在Java中 抽象原型角色通常实现了Cloneable接口 具体原型 ConcretePrototype 角色 被复制的对象 此角色需要实现抽象的原型角色所要求的接口 原型管理器 PrototypeManager 角色 创建具体原型类的对象 并记录每一个被创建的对象 5 1带原型管理器的原型模式实现 原型管理器 importjava util HashMap publicclassSpoonManager privateHashMaphm null privatestaticSpoonManagerspoonManager null privateSpoonManager hm newHashMap publicstaticsynchronizedSpoonManagergetSpoonManager if spoonManager null spoonManager newSpoonManager returnspoonManager publicvoidregister Stringname Objectprototype hm put name prototype publicvoidunRegister Stringname hm remove name publicObjectgetSpoon Stringname Objecto null if hm containsKey name o hm get name else try 自动查找原型管理器里不存在的类 并动态生成它o Class forName name newInstance this register name o catch Exceptione System out println class name don tdefine e getMessage e printStackTrace return AbstractSpoon o clone 5 2带原型管理器的原型模式实现 客户 publicclassClient paramargs publicstaticvoidmain String args AbstractSpoonsoupSpoon newSoupSpoon AbstractSpoonsaladSpoon newSaladSpoon SpoonManagerspoonManager SpoonManager getSpoonManager spoonManager register prototype test SoupSpoon soupSpoon spoonManager register prototype test SaladSpoon saladSpoon AbstractSpoonsoupSpoon2 AbstractSpoon spoonManager getSpoon prototype test SoupSpoon AbstractSpoonsaladSpoon2 AbstractSpoon spoonManager getSpoon prototype test SaladSpoon System out println soupSpoon hashCode System out println soupSpoon2 hashCode System out println saladSpoon hashCode System out println saladSpoon2 hashCode 6 JavaScript中的prototype应用 下面是一个比较实际的web应用中的例子 通过现有的dom元素对象 创建了一个新的副本 这个副本dom元素并没有使用document createElement方法创建 TestDivvartestClone document getElementById test cloneNode true document body appendChild testClone 6 JavaScript中的prototype应用 浅拷贝 functionWriter name sex this name name this sex sex functionBook name pages price writer this name name this pages pages this price price this writer writer Book prototype clone function 深拷贝浅拷贝的区别就在这个function里returnnewBook this name this pages this price this writer varwriter newWriter 佘丹 男 varbookName 深入解析原型模式 varmyBook newBook bookName 611 70 writer varotherBook myBook clone myBook name 不是深入解析原型模式 值类型的修改不会相互影响alert myBook name otherBook name 所以这里打印 不是深入解析原型模式 深入解析原型模式myBook writer name 不是佘丹 引用类型的修改会相互影响 因为他们引用同个内存地址alert myBook writer name otherBook writer name 所以这里打印 不是佘丹 不是佘丹 6 JavaScript中的prototype应用 深拷贝 functionWriter name sex this name name this sex sex functionBook name pages price writer this name name this pages pages this price price this writer writer Book prototype clone function 深拷贝浅拷贝的区别就在这个function里varwriter newWriter this writer name this writer sex returnnewBook this name this pages this price writer varwriter newWriter 佘丹 男 varbookName 深入解析原型模式 varmyBook newBook bookName 611 70 writer varotherBook myBook clone myBook name 不是深入解析原型模式 值类型的修改不会相互影响alert myBook name otherBook name 所以这里打印 不是深入解析原型模式 深入解析原型模式myBook writer name 不是佘丹 深拷贝 引用已经指向不同内存地址 修改不会相互影响alert myBook writer name otherBook writer name 所以这里打印 不是佘丹 佘丹 6 JavaScript中的prototype应用 原型管理器 StyleTestfunctionStyleItem fontSize color 类定义this fontSize fontSize this color color StyleItem prototype clone function return fontSize this fontSize color this color varStyleManager 原型管理器getStyle function key if this key returnthis key clone 预创建类可能的状态集合对象StyleManager big newStyleItem 16px 000 StyleManager normal newStyleItem 14px 333 StyleManager small newStyleItem 12px 666 无需再通过new来创建StyleItem类的对象了varel document getElementById styletest varstyle StyleManager getStyle small for varkinstyle el style k style k 7 深入JavaScript的prototype Javascript中的面向对象机制是通过prototype实现的 在new一个对象的时候 其实并没有为每一个对象创建每个prototype成员的副本 而是将对象成员指针指向prototype成员 下面程序可以验证这点 functionTest Test prototype alert function alert test vartest1 newTest vartest2 newTest alert test1 alert test2 alert test1 constructor prototype alert function alert test1 test2 alert 7 深入JavaScript的prototype 此外 JScript中对象的prototype属性 是用来返回对象类型原型的引用的 所有JScript内部对象都有只读的prototype属性 但可以向其原型中动态添加功能 属性和方法 而且对象的新实例会 继承 赋予该对象原型的操作 下面是三个经典的prototype属性的使用示例 1 为脚本环境内建对象添加方法 String prototype trim returnthis replace s s g 2 为用户自定义类添加方法 functionTestObject name this m Name name TestObject prototype ShowName fun

温馨提示

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

评论

0/150

提交评论