设计模式-原型模式课件.ppt
《设计模式-原型模式课件.ppt》由会员分享,可在线阅读,更多相关《设计模式-原型模式课件.ppt(27页珍藏版)》请在沃文网上搜索。
1、设计模式 原型(Prototype)模式 Session3 By xx1st Jul 2008原型(原型(Prototype)模式模式通过给出一个原型对象来指明所要创建的对象类型,然后用拷贝通过给出一个原型对象来指明所要创建的对象类型,然后用拷贝这个原型对象的办法创建出更多的同类型对象。这个原型对象的办法创建出更多的同类型对象。孙大圣的毫毛孙大圣的毫毛孙悟空在与黄风怪的战斗中,孙悟空在与黄风怪的战斗中,“使一个身外身的手段:把毫毛揪使一个身外身的手段:把毫毛揪下一把,用口嚼得粉碎,望上一喷,叫声下一把,用口嚼得粉碎,望上一喷,叫声变变,变有百十个行,变有百十个行者,都是一样得打扮,各执一根铁棒
2、,把那怪围在空中。者,都是一样得打扮,各执一根铁棒,把那怪围在空中。”换而换而言之,孙悟空可以根据自己的形象,拷贝出很多言之,孙悟空可以根据自己的形象,拷贝出很多“身外身身外身”来。来。孙悟空这种身外身的手段在面向对象设计领域里叫原型孙悟空这种身外身的手段在面向对象设计领域里叫原型(Prototype)模式。模式。1 1,JavaJava对原型模式的支持对原型模式的支持在在Java里面,我们可以通过里面,我们可以通过Clone()方法实现原型模式。任何类,只要方法实现原型模式。任何类,只要想支持克隆,必须实现想支持克隆,必须实现Cloneable接口。接口。Cloneable接口中有接口中有C
3、lone方法方法,可以在类中复写实现自定义的克隆方法。克隆的实现方法有三种:浅,可以在类中复写实现自定义的克隆方法。克隆的实现方法有三种:浅拷贝、深拷贝和完全拷贝。拷贝、深拷贝和完全拷贝。(1)浅拷贝浅拷贝被拷贝对象的所有变量都含有与原来的对象相同的值,而所有的对其他被拷贝对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。换言之,浅拷贝仅仅拷贝所考虑的对对象的引用仍然指向原来的对象。换言之,浅拷贝仅仅拷贝所考虑的对象,而不拷贝它所引用的对象。象,而不拷贝它所引用的对象。(2)深拷贝深拷贝被拷贝对象的所有变量都含有与原来的对象相同的值,除去那些引用其被拷贝对象
4、的所有变量都含有与原来的对象相同的值,除去那些引用其他对象的变量。那些引用其他对象的变量将指向被拷贝过的新对象,而他对象的变量。那些引用其他对象的变量将指向被拷贝过的新对象,而不再是原有的那些被引用的对象。换言之,深拷贝把要拷贝的对象所引不再是原有的那些被引用的对象。换言之,深拷贝把要拷贝的对象所引用的对象都拷贝了一遍。用的对象都拷贝了一遍。(3)完全拷贝完全拷贝完全拷贝不仅把要拷贝的对象所直接引用的对象都拷贝了一遍,完全拷贝不仅把要拷贝的对象所直接引用的对象都拷贝了一遍,还把该还把该对象间接引用到的所有对象也都拷贝了一遍。这是最彻底的一种拷贝。对象间接引用到的所有对象也都拷贝了一遍。这是最彻
5、底的一种拷贝。2,JavaJava的的clone()clone()方法方法 Cloneprotected protected ObjectObject clone()throws clone()throws CloneNotSupportedExceptionCloneNotSupportedExceptionThismethodmaybecalledtocreateanewcopyoftheObject.Thetypicalbehaviorisasfollows:o=o.clone()o=o.clone()isfalseo.o.getClassgetClass()=o.clone().()=
6、o.clone().getClassgetClass()()istrueo.equals(o)o.equals(o)istrueHowever,thesearenotstrictrequirements,andmaybeviolatedifnecessary.Ofthethreerequirements,thelastisthemostcommonlyviolated,particularlyifthesubclassdoesnotoverrideequals(Object)equals(Object)55.IftheObjectyoucallclone()ondoesnotimplement
7、Cloneable(whichisaplaceholderinterface),thenaCloneNotSupportedExceptionisthrown.NoticethatObjectdoesnotimplementCloneable;thismethodexistsasaconvenienceforsubclassesthatdo.ObjectsimplementationofcloneallocatesspaceforthenewObjectusingthecorrectclass,withoutcallinganyconstructors,andthenfillsinalloft
8、henewfieldvalueswiththeoldfieldvalues.Thus,itisashallowcopy.However,subclassesarepermittedtomakeadeepcopy.AllarraytypesimplementCloneable,andoverridethismethodasfollows(itshouldneverfail):public Object clone()try super.clone();catch(public Object clone()try super.clone();catch(CloneNotSupportedExcep
9、tionCloneNotSupportedException e)throw new e)throw new InternalErrorInternalError(e.(e.getMessagegetMessage();();2,JavaJava的的clone()clone()方法方法 clone方法将对象复制了一份并返回给调用者。一般而方法将对象复制了一份并返回给调用者。一般而言,言,clone()方法满足:()方法满足:对任何的对象对任何的对象x,都有,都有x.clone()!=x克隆对象与原对象不是同一个对象克隆对象与原对象不是同一个对象对任何的对象对任何的对象x,都有,都有x.clon
10、e().getClass()=x.getClass()克隆对象与原对象的类型一样克隆对象与原对象的类型一样如果对象如果对象x的的equals()方法定义恰当,那么方法定义恰当,那么x.clone().equals(x)应该成立。应该成立。Java中对象的克隆中对象的克隆为了获取对象的一份拷贝,我们可以利用为了获取对象的一份拷贝,我们可以利用Object类的类的clone()方法。方法。在派生类中覆盖基类的在派生类中覆盖基类的clone()方法,并声明为方法,并声明为public。在派生类的在派生类的clone()方法中,调用方法中,调用super.clone()。在派生类中实现在派生类中实现C
11、loneable接口。接口。3,JavaJava的类拷贝实现代码的类拷贝实现代码classStudentimplementsCloneableStringname;intage;Student(Stringname,intage)this.name=name;this.age=age;publicObjectclone()Objecto=null;tryo=(Student)super.clone();/Object中的中的clone()识别出你要复制的是哪一个对象。识别出你要复制的是哪一个对象。catch(CloneNotSupportedExceptione)System.out.prin
12、tln(e.toString();returno;publicstaticvoidmain(Stringargs)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中的 cl
13、one()识别出你要复制的是哪一个对象,然后为此对象分配空间,并进行对象的复制,将原始对象的内容一一复制到新对象的存储空间中。继承自java.lang.Object类的clone()方法是浅复制。后面的代码可以证明。浅拷贝3,JavaJava的类拷贝实现代码的类拷贝实现代码classProfessorStringname;intage;Professor(Stringname,intage)this.name=name;this.age=age;classStudentimplementsCloneableStringname;/常量对象。常量对象。intage;Professorp;/学生学
14、生1和学生和学生2的引用值都是一样的引用值都是一样的。的。Student(Stringname,intage,Professorp)this.name=name;this.age=age;this.p=p;publicObjectclone()Studento=null;tryo=(Student)super.clone();catch(CloneNotSupportedExceptione)System.out.println(e.toString();/o.p=(Professor)p.clone();returno;publicstaticvoidmain(Stringargs)Prof
15、essorp=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,JavaJava的类拷贝实现代码的类拷贝实现代码classProfessorimplementsCloneableStringname;intage;Professor(S
16、tringname,intage)this.name=name;this.age=age;publicObjectclone()Objecto=null;tryo=super.clone();catch(CloneNotSupportedExceptione)System.out.println(e.toString();returno;classStudentimplementsCloneableStringname;/常量对象。常量对象。intage;Professorp;/学生学生1和学生和学生2的引用值都是一样的引用值都是一样的。的。Student(Stringname,intage,
17、Professorp)this.name=name;this.age=age;this.p=p;publicObjectclone()Studento=null;tryo=(Student)super.clone();catch(CloneNotSupportedExceptione)System.out.println(e.toString();o.p=(Professor)p.clone();returno;publicstaticvoidmain(Stringargs)Professorp=newProfessor(“wanGWu”,50);Students1=newStudent(“z
18、hangsan”,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,JavaJava的类拷贝实现代码的类拷贝实现代码classProfessorimplementsSerializableStringname;intage;Professor(Stringname,intage)this.name=name;this.age=age;classStuden
19、timplementsSerializableStringname;/常量对象。常量对象。intage;Professorp;/学生学生1和学生和学生2的引用值都是一样的。的引用值都是一样的。Student(Stringname,intage,Professorp)this.name=name;this.age=age;this.p=p;publicObjectfullClone()throwsIOException,OptionalDataException,ClassNotFoundException/将对象写到流里将对象写到流里ByteArrayOutoutStreambo=newByt
20、eArrayOutputStream();ObjectOutputStreamoo=newObjectOutputStream(bo);oo.writeObject(this);/从流里读出来从流里读出来ByteArrayInputStreambi=newByteArrayInputStream(bo.toByteArray();ObjectInputStreamoi=newObjectInputStream(bi);return(oi.readObject();publicstaticvoidmain(Stringargs)Professorp=newProfessor(wangwu,50)
21、;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接口,然后把对象(实际上只是对象的一个拷贝)接口,然后把对象(实际上只是对象的一个拷贝)写到一个流里(腌成干菜),再从流里读出来(把
22、干菜回鲜),便可以重建对象。写到一个流里(腌成干菜),再从流里读出来(把干菜回鲜),便可以重建对象。4,PrototypePrototype模式的结构模式的结构客客户(Client)角色角色:客客户类提出提出创建建对象的象的请求求。抽象原型抽象原型(Prototype)角色角色:这是一个抽象角色是一个抽象角色,通常由一个接口通常由一个接口类或抽象类实现。此角色给出所有的具体原型类或抽象类实现。此角色给出所有的具体原型类所需的接口所需的接口。在。在Java中,中,抽象原型角色通常抽象原型角色通常实现了了Cloneable接口接口。具体原型具体原型(ConcretePrototype)角色角色:被
23、复制的被复制的对象象。此角色需要此角色需要实现抽象原型角色所要求的接口抽象原型角色所要求的接口。4.1 PrototypePrototype模式实现模式实现-抽象原型抽象原型public abstract class AbstractSpoon implements Cloneable String spoonName;public void setSpoonName(String spoonName)this.spoonName=spoonName;public String getSpoonName()return this.spoonName;public Object clone()O
24、bject object=null;try object=super.clone();catch(CloneNotSupportedException exception)System.err.println(AbstractSpoon is not Cloneable);return object;4.2 PrototypePrototype模式实现模式实现-具体原型具体原型public class SaladSpoon extends AbstractSpoon public SaladSpoon()setSpoonName(Salad Spoon);public class SoupSp
- 1.请仔细阅读文档,确保文档完整性,对于不预览、不比对内容而直接下载带来的问题本站不予受理。
- 2.下载的文档,不会出现我们的网址水印。
- 3、该文档所得收入(下载+内容+预览)归上传者、原创作者;如果您是本文档原作者,请点此认领!既往收益都归您。
下载文档到电脑,查找使用更方便
20 积分
下载 | 加入VIP,下载更划算! |
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 设计 模式 原型 课件
