设计模式之原型模式Prototype目录CONTENT1.原型模式的概念及特点2.原型模式结构及功能3.原型模式示例4.原型模式总结1.原型模式的概念及特点原型模式定义•原型模式就是通过一个原型对象来表明要创建的对象类型,然后用复制这个原型对象的方法来创建更多同类型的对象。•原型模式允许一个对象再创建另外一个可定制的对象,根本无需知道任何如何创建的细节。1.原型模式的概念及特点为什么需要原型模式?•在画图工具里,要画圆只需要拖动工具条的画圆工具到绘图区即可,而不需要从头开始一点一点地画一个圆,而且如果需要不同的大小和颜色的圆,只需要复制几个圆,然后再修改他们的大小和颜色即可。这就给使用者带来了很大的方便,即使用者不需要知道对象是如何创建的,只需要复制一个已有的对象,然后在其上面进行修改以得到自己想要的对象,这就是原型模式的具体应用。1.原型模式的概念及特点为什么需要原型模式?•引入原型模式的本质在于利用已有的一个原型对象,快速的生成和原型对象一样的实例。你有一个A的实例a:Aa=newA();现在你想生成和A一样的一个实例b,按照原型模式,应该是这样:Ab=a.Clone();而不是重新再new一个A对象。通过上面这句话就可以得到一个和a一样的实例,确切的说,应该是它们的数据成员是一样的。原型模式模式是返回了一个A对象而没有使用new操作。1.原型模式的概念及特点原型模式与工厂模式的异同•原型模式应用于希望系统独立于产品的创建、表示和构成时,这和工厂模式很类似。事实上,和工厂模式相同的是,原型模式同样对客户隐藏了对象的创建工作,但是,与工厂模式通过对一个类进行实例化来构造新对象不同的是,原型模式是通过拷贝一个现有对象生成新对象的。工厂模式适用于产品种类有限的情况下,当产品数量巨大或需要提供动态产品增删等性能时,使用原型模式具有更强的适应性。4.原型模式总结2.原型模式结构及功能原型模式的一般结构•原型模式的一般结构如下:2.原型模式结构及功能原型模式的一般结构•客户角色:客户调用端,客户使用原型对象复制出需要的对象。•抽象原型角色:定义一个原型的抽象定义,其中包含一个复制自身的接口。•具体原型角色:作为原型被复制的具体对象,需实现抽象原型所定义的接口。2.原型模式结构及功能•原型管理器角色:该角色用于创建具体的原型类对象,并且记录每一个被创建的对象并且把已经创建过的对象保存下来。换句话说就是先创建对象并将其保存下来(由管理器完成)然后利用Clone()方法来创建新对象3.原型模式示例原型模式示例•背景:前几天,我很不幸把屋门的钥匙给弄丢了,结果进不了家门。万幸的是,舍友那儿还有一把,于是第二天我拿了她的那把去配钥匙。另外,她还让我顺便给她配一把橱柜的钥匙。现在配个钥匙真是简单,把钥匙给他,他直接找一个合适的钥匙胚子,把我的钥匙夹在配钥匙机的一端,胚子夹在另一端,一开电源,一把标尺比着我的钥匙齿型走一遍,砂轮就在胚子上复制出一把钥匙来!一分钟不到,两把新钥匙就搞定了!3.原型模式实例使用UML序列图直观解释3.原型模式实例使用类图描述3.原型模式实例程序代码如下:namespace原型模式...{//抽象钥匙原型publicabstractclassKey...{privatestringname;publicstringName...{get...{returnname;}set...{name=value;}}privatestringowner;publicstringOwner...{get...{returnowner;}set...{owner=value;}}publicKey(stringname,stringowner)...{this.name=name;this.owner=owner;}//钥匙复制自身的抽象定义publicabstractKeyClone();}}3.原型模式实例//大门钥匙publicclassGateKey:Key...{publicGateKey(stringowner):base(GateKey,owner)...{}publicoverrideKeyClone()...{returnnewGateKey(this.Owner);}}//橱柜钥匙publicclassCabinetKey:Key...{publicCabinetKey(stringowner):base(CabinetKey,owner)...{}publicoverrideKeyClone()...{returnnewCabinetKey(this.Owner);}}3.原型模式实例//客户调用方法publicclassClient...{publicstaticvoidMain(string[]args)...{KeyoldGateKey,newGateKey,oldCabinetKey,newCabinetKey;oldGateKey=newGateKey(“Him);newGateKey=oldGateKey.Clone();newGateKey.Owner=Me;oldCabinetKey=newCabinetKey(Me);newCabinetKey=oldCabinetKey.Clone();newCabinetKey.Owner=“Him;Console.WriteLine(oldGateKey);Console.WriteLine(newGateKey);Console.WriteLine(oldCabinetKey);Console.WriteLine(newCabinetKey);}}}3.原型模式实例原型管理器的应用publicclassKeyManager...{privateSystem.Collections.Hashtablekeys=newSystem.Collections.Hashtable();publicKeythis[stringname]...{set...{keys.Add(name,value);}get...{return(Key)keys[name];}}}3.原型模式实例//客户调用方法publicclassClient...{publicstaticvoidMain(string[]args)...{KeyManagerkeyManager=newKeyManager();keyManager[gate]=newGateKey(Him);keyManager[key2]=newGeneralKey(key2,Him);keyManager[key3]=newGeneralKey(key3,Him);keyManager[key4]=newGeneralKey(key4,“Him);keyManager[key5]=newGeneralKey(key5,Him);KeynewKey=(Key)keyManager[key2].Clone();newKey.Name=Office;newKey.Owner=Me;}}}3.原型模式实例4.原型模式总结原型模式的优点•1、运行时刻增加和删除产品。•2、改变值以指定新对象。•3、改变结构以指定新对象。•4、减少子类的构造。•5、用类动态配置应用。4.原型模式总结原型模式的缺点4.原型模式总结Prototype模式最主要缺点就是每个类必须配备一个克隆方法,而且这个克隆方法需要对类的功能进行通盘考虑,这对全新的类来说不是很难,但对已有的类进行改造时不一定是件容易的事。原型模式实现要点•使用一个原型管理器。当一个系统中原型数目不固定时,要保持一个可用原型的注册表。客户不会自己来管理原型,但会在注册表中存储和检索原型。客户在克隆一个原型前会向注册表请求该原型。我们称这个注册表为原型管理器。•实现克隆操作Prototype模式最困难的部分在于正确实现Clone操作。当对象结构包含循环引用时,这尤为棘手。4.原型模式总结原型模式实现要点•初始化克隆对象。当一些客户对克隆对象已经相当满意时,另一些客户将会希望使用他们所选择的一些值来初始化该对象的一些或是所有的内部状态。谢谢大家!