首页 > 代码库 > 设计模式------原型模式
设计模式------原型模式
原型模式(PrototypePattern)是一种对象创建型模式,用原型实例指定创建对象的种类,并且通过复制这些原型创建新的对象。原型模式允许一个对象再创建另外一个可定制的对象,无须知道任何创建的细节。
原型模式的基本工作原理是通过将一个原型对象传给那个要发动创建的对象,这个要发动创建的对象通过请求原型对象拷贝原型自己来实现创建过程。其实很多软件提供的复制(Ctrl +C)和粘贴(Ctrl + V)操作就是原型模式的应用,复制得到的对象与原型对象是两个类型相同但内存地址不同的对象,通过原型模式可以大大提高对象的创建效率。
1.角色:
抽象原型类(Prototype):声明一个克隆自身的接口。
具体原型类(ConcretePrototype):实现一个克隆自身的操作。
客户类(Client):让原型克隆自身从而创建一个新的对象。
结构图:
2.适用情况:
(1)创建新对象成本较大,新的对象可以通过原型模式对已有对象进行复制来获得,如果是相似对象,则可以对其属性稍作修改。
(2)如果系统要保存对象的状态,而对象的状态变化很小,或者对象本身占内存不大的时候,也可以使用原型模式配合备忘录模式来应用。相反,如果对象的状态变化很大,或者对象占用的内存很大,那么采用状态模式会比原型模式更好。
(3)需要避免使用分层次的工厂类来创建分层次的对象,并且类的实例对象只有一个或很少的几个组合状态,通过复制原型对象得到新实例可能比使用构造函数创建一个新实例更加方便。
3.优缺点
(1)优点:
?当创建新的对象实例较为复杂时,使用原型模式可以简化对象的创建过程,通过一个已有实例可以提高新实例的创建效率。
?可以动态增加或减少产品类。
?原型模式提供了简化的创建结构。
?可以使用深克隆的方式保存对象的状态。
(2)缺点:
?需要为每一个类配备一个克隆方法,而且这个克隆方法需要对类的功能进行通盘考虑,这对全新的类来说不是很难,但对已有的类进行改造时,不一定是件容易的事,必须修改其源代码,违背了“开闭原则”。
?在实现深克隆时需要编写较为复杂的代码。
4.简历的原型实现:
注:.NET在system命名空间中提供了IChoneable接口,它有唯一的方法Clone()。这样只需实现这个接口就可以完成原型模式了。
简历类:
<span style="font-family:Microsoft YaHei;font-size:18px;">//简历 class Resume : ICloneable { private string name; private string sex; private string age; private string timeArea; private string company; public Resume(string name) { this.name = name; } //设置个人信息 public void SetPersonalInfo(string sex, string age) { this.sex = sex; this.age = age; } //设置工作经历 public void SetWorkExperience(string timeArea, string company) { this.timeArea = timeArea; this.company = company; } //显示 public void Display() { Console.WriteLine("\n{0} {1} {2}", name, sex, age); Console.WriteLine("工作经历:{0} {1}", timeArea, company); } public Object Clone() { return (Object)this.MemberwiseClone(); } }</span>
客户端调用:
<span style="font-family:Microsoft YaHei;font-size:18px;"> static void Main(string[] args) { Resume a = new Resume("大鸟"); a.SetPersonalInfo("男", "29"); a.SetWorkExperience("1998-2000", "XX公司"); Resume b = (Resume)a.Clone(); b.SetWorkExperience("1998-2006", "YY企业"); Resume c = (Resume)a.Clone(); c.SetPersonalInfo("男", "24"); a.Display(); b.Display(); c.Display(); Console.Read(); }</span>窗口显示:
评价:
原型模式的使用,使得不用重新初始化对象,而是动态地获得对象运行时的状态。即隐藏了对象创建的细节,又大大地提高了性能。
4.浅复制&深复制
通常情况下,一个类包含一些成员对象,在使用原型模式克隆对象时,根据其成员对象是否也克隆,原型模式可以分为两种形式:深复制(克隆)和浅复制(克隆)。
(1)浅复制:
被复制对象的所有变量都含有与原来对象相同的值,而所有的对其他对象的引用都仍然指向原来的对象。
(2)深复制:把引用对象的变量指向复制过的新对象,而不是原有的被引用的对象。
举个例子,使用浅复制复制一份邮件时,不会复制邮件的附件;而使用深复制复制邮件时,会同时复制附件。
(3)C#深复制与浅复制:
C#数据类型大体分为值类型(valuetype)与引用类型(referencetype)。对于值类型数据,复制的时候直接将数据复制给另外的变量,而对于引用型变量而言,复制时只是复制了其引用。复制引用的方式叫浅复制,而逐一复制被复制对象的数据成员的方式称为深复制。.NET中Object类提供了一个MemberwiseClone方法实现的就是上述机制。再比如,数据集对象DataSet的Clone()方法用来复制DataSet的结构,不复制DataSet的数据,实现了原型模式的浅复制;DataSet的Copy()方法不但复制结构,还复制数据,实现了深复制。