09 设计模式教学课件_第1页
09 设计模式教学课件_第2页
09 设计模式教学课件_第3页
09 设计模式教学课件_第4页
09 设计模式教学课件_第5页
已阅读5页,还剩34页未读 继续免费阅读

下载本文档

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

文档简介

原型(Prototype)模式,原型(Prototype)模式,原型模式的用意是:通过给出一个原型对象来指明所要创建的对象类型,然后用复制这个原型对象的办法创建出更多的同类型对象。,Java对原型模式的支持,Java语言中已经提供了clone方法,定义在Object类中,需要实现克隆功能的类,只需要实现java.lang.Cloneable接口即可,C#对原型模式的支持,在C#里面,我们可以很容易的通过Clone()方法实现原型模式。任何类,只要想支持克隆,必须实现C#中的ICloneable接口。ICloneable接口中有一Clone方法,可以在类中复写,实现自定义的克隆方法。克隆的实现方法有两种:浅拷贝(shallowcopy)与深拷贝(deepcopy)。,浅拷贝:只负责克隆按值传递的数据(比如基本数据类型、String类型)深拷贝:除了浅拷贝要克隆的值外,还负责克隆引用类型(属性的类型也是对象)的数据。需要注意的是执行深拷贝后,原来的对象和新创建的对象不会共享任何东西;改变一个对象对另外一个对象没有任何影响。,Prototype模式的结构:,客户(Client)角色:客户类提出创建对象的请求。,抽象原型(Prototype)角色:这是一个抽象角色,通常由一个C#接口或抽象类实现。此角色给出所有的具体原型类所需的接口。在C#中,抽象原型角色通常实现了ICloneable接口。具体原型(ConcretePrototype)角色:被复制的对象。此角色需要实现抽象原型角色所要求的接口。,抽象原型(Prototype)角色,abstractclassPrototypeprivatestringid;publicPrototype(stringid)this.id=id;publicstringIdgetreturnid;abstractpublicPrototypeClone();,具体原型(ConcretePrototype)角色1:,classConcretePrototype1:Prototype/ConstructorspublicConcretePrototype1(stringid):base(id)/MethodsoverridepublicPrototypeClone()/Shallowcopyreturn(Prototype)this.MemberwiseClone();,MemberwiseClone方法创建一个浅表副本,方法是创建一个新对象,然后将当前对象的非静态字段复制到该新对象。如果字段是值类型的,则对该字段执行逐位复制。如果字段是引用类型,则复制引用但不复制引用的对象;因此,原始对象及其复本引用同一对象。,具体原型(ConcretePrototype)角色2:,classConcretePrototype2:Prototype/ConstructorspublicConcretePrototype2(stringid):base(id)/MethodsoverridepublicPrototypeClone()/Shallowcopyreturn(Prototype)this.MemberwiseClone();,classClientpublicstaticvoidMain(stringargs)/CreatetwoinstancesandcloneeachConcretePrototype1p1=newConcretePrototype1(I);ConcretePrototype1c1=(ConcretePrototype1)p1.Clone();Console.WriteLine(Cloned:0,c1.Id);ConcretePrototype2p2=newConcretePrototype2(II);ConcretePrototype2c2=(ConcretePrototype2)p2.Clone();Console.WriteLine(Cloned:0,c2.Id);,简历的原型实现,classResume:ICloneableprivatestringname;privatestringsex;privatestringage;privatestringtimeArea;privatestringcompany;publicResume(stringname)=name;,/设置个人信息publicvoidSetPersonalInfo(stringsex,stringage)this.sex=sex;this.age=age;/设置工作经历publicvoidSetWorkExperience(stringtimeArea,stringcompany)this.timeArea=timeArea;pany=company;,/显示publicvoidDisplay()Console.WriteLine(012,name,sex,age);Console.WriteLine(工作经历:01,timeArea,company);publicObjectClone()return(Object)this.MemberwiseClone();,staticvoidMain(stringargs)Resumea=newResume(大鸟);a.SetPersonalInfo(男,29);a.SetWorkExperience(1998-2000,XX公司);Resumeb=(Resume)a.Clone();b.SetWorkExperience(1998-2006,YY企业);Resumec=(Resume)a.Clone();c.SetPersonalInfo(男,24);a.Display();b.Display();c.Display();Console.Read();,优点,想要改某份简历,只需要对这份简历作一定的修改就可以,不会影响到其它简历,相同的部分就不用再重复一般在初始化的信息不发生变化的情况下,克隆是最好的办法。即隐藏了创建的细节,又对性能是大大的提高。,浅复制与深复制,MemberwiseClone方法创建一个浅表副本.如果“简历”类当中有对象的引用,那么引用的对象数据是不会被克隆过来的,举例:设立“工作经历类”,/工作经历classWorkExperienceprivatestringworkDate;publicstringWorkDategetreturnworkDate;setworkDate=value;privatestringcompany;publicstringCompanygetreturncompany;setcompany=value;,classResume:ICloneableprivatestringname;privatestringsex;privatestringage;privateWorkExperiencework;publicResume(stringname)=name;work=newWorkExperience();/设置个人信息publicvoidSetPersonalInfo(stringsex,stringage)this.sex=sex;this.age=age;,/设置工作经历publicvoidSetWorkExperience(stringworkDate,stringcompany)work.WorkDate=workDate;work.Company=company;/显示publicvoidDisplay()Console.WriteLine(012,name,sex,age);Console.WriteLine(工作经历:01,work.WorkDate,work.Company);publicObjectClone()return(Object)this.MemberwiseClone();,staticvoidMain(stringargs)Resumea=newResume(大鸟);a.SetPersonalInfo(男,29);a.SetWorkExperience(1998-2000,XX公司);Resumeb=(Resume)a.Clone();b.SetWorkExperience(1998-2006,YY企业);Resumec=(Resume)a.Clone();c.SetPersonalInfo(男,24);c.SetWorkExperience(1998-2003,ZZ企业);a.Display();b.Display();c.Display();Console.Read();,客户端,出错原因:,MemberwiseClone()。对引用类型,就只是复制了引用,对引用的对象还是指向了原来的对象。此题中,三个引用都指向了同一个对象,复制,浅复制:被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用都仍然指向原来的对象。深复制:把引用对象的变量指向复制过的新对象,而不是原有的被引用的对象。,简历的深复制实现,/工作经历classWorkExperience:ICloneableprivatestringworkDate;publicstringWorkDategetreturnworkDate;setworkDate=value;privatestringcompany;publicstringCompanygetreturncompany;setcompany=value;publicObjectClone()return(Object)this.MemberwiseClone();,classResume:ICloneableprivatestringname;privatestringsex;privatestringage;privateWorkExperiencework;publicResume(stringname)=name;work=newWorkExperience();privateResume(WorkExperiencework)this.work=(WorkExperience)work.Clone();/设置个人信息publicvoidSetPersonalInfo(stringsex,stringage)this.sex=sex;this.age=age;,提供Clone方法调用的私有构造函数,以便克隆“工作经历”的数据,/设置工作经历publicvoidSetWorkExperience(stringworkDate,stringcompany)work.WorkDate=workDate;work.Company=company;/显示publicvoidDisplay()Console.WriteLine(012,name,sex,age);Console.WriteLine(工作经历:01,work.WorkDate,work.Company);publicObjectClone()Resumeobj=newResume(this.work);=;obj.sex=this.sex;obj.age=this.age;returnobj;,调用私有的构造方法,让“工作经历”克隆完成,然后再给这个“简历”对象的相关字段赋值,最终返回一个深复制的简历对象,staticvoidMain(stringargs)Resumea=newResume(大鸟);a.SetPersonalInfo(男,29);a.SetWorkExperience(1998-2000,XX公司);Resumeb=(Resume)a.Clone();b.SetWorkExperience(1998-2006,YY企业);Resumec=(Resume)a.Clone();c.SetPersonalInfo(男,24);c.SetWorkExperience(1998-2003,ZZ企业);a.Display();b.Display();c.Display();Console.Read();,客户端,深拷贝/浅拷贝举例,下面给出浅拷贝与深拷贝的两个例子,例子使用了ICloneable接口。C#中的数组是引用型的变量,我们通过数组来进行演示:,浅拷贝:,classShallowCopy:ICloneablepublicintv=1,2,3;publicObjectClone()returnthis.MemberwiseClone();publicvoidDisplay()foreach(intiinv)Console.Write(i+,);Console.WriteLine();,classClientpublicstaticvoidMain()ShallowCopysc1=newShallowCopy();ShallowCopysc2=(ShallowCopy)sc1.Clone();sc1.v0=9;sc1.Display();sc2.Display();,ShallowCopy对象实现了一个浅拷贝,因此当对sc1进行克隆时,其字段v并没有克隆,这导致sc1与sc2的字段v都指向了同一个v,因此,当修改了sc1的v0后,sc2的v0也发生了变化。,深复制,classDeepCopy:ICloneablepublicintv=1,2,3;publicDeepCopy()/供Clone方法调用的私有构造函数privateDeepCopy(intv)this.v=(int)v.Clone();publicObjectClone()/构造一个新的DeepCopy对象,构造参数为原有对象中使用的vreturnnewDeepCopy(this.v);publicvoidDisplay()foreach(intiinv)Console.Write(i+,);Console.WriteLine();,classClientpublicstaticvoidMain()DeepCopydc1=newDeepCopy();DeepCopydc2=(DeepCopy)dc1.Clone();dc1.v0=9;dc1.Display();dc2.Display();,这次在克隆的时候,不但克隆对象本身,连里面的数组字段一并克隆。因此,最终打印出来的dc1与dc2不同。,Prototype模式本质(原型引入的初衷),克隆生成对象你如果要生成一大批很相像的类的实例时,不用每次去做重复的赋值工作。如果你有一个类A,它有十个成员变量,现在你打算生成100个A的实例,而这些实例的变量值大部分相同(比如说七个相同),只有一小部分不一样(比如说三个),那么如果没有Prototype,那么你就得每次New一个A的对像,然后赋值,这样,你要重复100次同样的七个变量的赋值工作,显然,这样很麻烦。现在你有了原型,那么问题就简单了,你只要生成一个A的实例,再通过clone来生成其它的实例,然后再一一修改其它实例不同的地方。,Prototype模式与Factory模式的关系,虽然原型引入的初衷是像上面所说,但他实现起来,却完全可以达到工厂模式的郊果;而且,用起来甚至比工厂模式更方便、灵活。对于工厂模式与原形模式在功能上的这点巧合,也许是因为本来工厂模式和原型模式都是创建型模式(三种类型,行为、结构),这样,他们的基本功能都能生成对象,因而使得原型模式在功能上可以代替工厂模式。,工厂模式实现的生产产品的功能,关键是利用了继承的特性。也就是说,你生成的产品,一定是由同一个抽象产品类派生出来的。所以,在工厂模式下,你如果要生成一类产品,就要引入一个抽像产品类,然后再由它派生出具体产品。同样,在原型模

温馨提示

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

评论

0/150

提交评论